]> git.lizzy.rs Git - rust.git/commitdiff
Rollup merge of #87307 - michaelwoerister:pgo-unwind-msvc, r=nagisa
authorGuillaume Gomez <guillaume1.gomez@gmail.com>
Thu, 22 Jul 2021 11:39:23 +0000 (13:39 +0200)
committerGitHub <noreply@github.com>
Thu, 22 Jul 2021 11:39:23 +0000 (13:39 +0200)
Allow combining -Cprofile-generate and -Cpanic=unwind when targeting MSVC.

The LLVM limitation that previously prevented this has been fixed in LLVM 9 which is older than the oldest LLVM version we currently support.

Fixes https://github.com/rust-lang/rust/issues/61002.

r? ``@nagisa`` (or anyone else from ``@rust-lang/wg-llvm)``

525 files changed:
Cargo.lock
Cargo.toml
compiler/rustc_ast/src/mut_visit.rs
compiler/rustc_ast_lowering/src/item.rs
compiler/rustc_ast_lowering/src/lib.rs
compiler/rustc_ast_lowering/src/path.rs
compiler/rustc_builtin_macros/src/derive.rs
compiler/rustc_builtin_macros/src/deriving/clone.rs
compiler/rustc_builtin_macros/src/deriving/generic/ty.rs
compiler/rustc_codegen_ssa/Cargo.toml
compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs
compiler/rustc_error_codes/src/error_codes.rs
compiler/rustc_error_codes/src/error_codes/E0722.md [new file with mode: 0644]
compiler/rustc_error_codes/src/error_codes/E0757.md [new file with mode: 0644]
compiler/rustc_errors/src/emitter.rs
compiler/rustc_feature/src/active.rs
compiler/rustc_feature/src/removed.rs
compiler/rustc_hir/src/hir.rs
compiler/rustc_infer/src/infer/canonical/canonicalizer.rs
compiler/rustc_infer/src/infer/error_reporting/mod.rs
compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs
compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mismatched_static_lifetime.rs [new file with mode: 0644]
compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mod.rs
compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs
compiler/rustc_infer/src/infer/freshen.rs
compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs
compiler/rustc_infer/src/infer/mod.rs
compiler/rustc_lint/src/context.rs
compiler/rustc_lint/src/levels.rs
compiler/rustc_lint_defs/src/lib.rs
compiler/rustc_middle/src/hir/map/mod.rs
compiler/rustc_middle/src/lint.rs
compiler/rustc_middle/src/mir/interpret/error.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/ty/context.rs
compiler/rustc_middle/src/ty/print/pretty.rs
compiler/rustc_mir/src/borrow_check/diagnostics/region_errors.rs
compiler/rustc_mir/src/borrow_check/member_constraints.rs
compiler/rustc_mir/src/borrow_check/region_infer/mod.rs
compiler/rustc_mir/src/borrow_check/type_check/input_output.rs
compiler/rustc_mir/src/borrow_check/type_check/mod.rs
compiler/rustc_mir/src/interpret/memory.rs
compiler/rustc_mir/src/transform/check_consts/validation.rs
compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs
compiler/rustc_query_impl/src/keys.rs
compiler/rustc_session/src/config.rs
compiler/rustc_session/src/options.rs
compiler/rustc_span/src/hygiene.rs
compiler/rustc_trait_selection/src/opaque_types.rs
compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
compiler/rustc_trait_selection/src/traits/fulfill.rs
compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs
compiler/rustc_trait_selection/src/traits/query/normalize.rs
compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs
compiler/rustc_trait_selection/src/traits/select/mod.rs
compiler/rustc_trait_selection/src/traits/structural_match.rs
compiler/rustc_typeck/src/astconv/mod.rs
compiler/rustc_typeck/src/check/check.rs
compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs
compiler/rustc_typeck/src/check/fn_ctxt/mod.rs
compiler/rustc_typeck/src/check/gather_locals.rs
compiler/rustc_typeck/src/check/method/suggest.rs
compiler/rustc_typeck/src/check/mod.rs
compiler/rustc_typeck/src/check/wfcheck.rs
compiler/rustc_typeck/src/check/writeback.rs
compiler/rustc_typeck/src/collect.rs
compiler/rustc_typeck/src/collect/type_of.rs
compiler/rustc_typeck/src/hir_wf_check.rs
library/core/src/alloc/global.rs
library/core/src/iter/adapters/flatten.rs
library/core/tests/iter/adapters/flatten.rs
library/std/src/io/stdio.rs
library/std/src/sys/unix/args.rs
library/term/Cargo.toml [deleted file]
library/term/src/lib.rs [deleted file]
library/term/src/terminfo/mod.rs [deleted file]
library/term/src/terminfo/parm.rs [deleted file]
library/term/src/terminfo/parm/tests.rs [deleted file]
library/term/src/terminfo/parser/compiled.rs [deleted file]
library/term/src/terminfo/parser/compiled/tests.rs [deleted file]
library/term/src/terminfo/searcher.rs [deleted file]
library/term/src/terminfo/searcher/tests.rs [deleted file]
library/term/src/win.rs [deleted file]
library/test/Cargo.toml
library/test/src/console.rs
library/test/src/formatters/pretty.rs
library/test/src/formatters/terse.rs
library/test/src/lib.rs
library/test/src/term.rs [new file with mode: 0644]
library/test/src/term/terminfo/mod.rs [new file with mode: 0644]
library/test/src/term/terminfo/parm.rs [new file with mode: 0644]
library/test/src/term/terminfo/parm/tests.rs [new file with mode: 0644]
library/test/src/term/terminfo/parser/compiled.rs [new file with mode: 0644]
library/test/src/term/terminfo/parser/compiled/tests.rs [new file with mode: 0644]
library/test/src/term/terminfo/searcher.rs [new file with mode: 0644]
library/test/src/term/terminfo/searcher/tests.rs [new file with mode: 0644]
library/test/src/term/win.rs [new file with mode: 0644]
src/bootstrap/bootstrap.py
src/bootstrap/check.rs
src/bootstrap/compile.rs
src/bootstrap/doc.rs
src/bootstrap/lib.rs
src/bootstrap/native.rs
src/bootstrap/test.rs
src/bootstrap/tool.rs
src/doc/book
src/doc/edition-guide
src/doc/embedded-book
src/doc/reference
src/doc/rust-by-example
src/doc/rustc-dev-guide
src/doc/unstable-book/src/compiler-flags/force-warn.md [new file with mode: 0644]
src/doc/unstable-book/src/compiler-flags/force-warns.md [deleted file]
src/doc/unstable-book/src/language-features/impl-trait-in-bindings.md [deleted file]
src/librustdoc/config.rs
src/librustdoc/html/markdown.rs
src/librustdoc/html/render/print_item.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/storage.js
src/librustdoc/lib.rs
src/test/debuginfo/function-names.rs
src/test/debuginfo/generic-struct.rs
src/test/debuginfo/msvc-pretty-enums.rs
src/test/debuginfo/pretty-std-collections-hash.rs
src/test/debuginfo/pretty-std.rs
src/test/debuginfo/result-types.rs
src/test/debuginfo/type-names.rs
src/test/run-make/unstable-flag-required/Makefile
src/test/run-make/unstable-flag-required/force-warn.stderr [new file with mode: 0644]
src/test/run-make/unstable-flag-required/force-warns.stderr [deleted file]
src/test/rustdoc-gui/default-settings.goml [new file with mode: 0644]
src/test/rustdoc-gui/docblock-table-overflow.goml [new file with mode: 0644]
src/test/rustdoc-gui/item-summary-table.goml [new file with mode: 0644]
src/test/rustdoc-gui/src/Cargo.lock [deleted file]
src/test/rustdoc-gui/src/Cargo.toml [deleted file]
src/test/rustdoc-gui/src/implementors/Cargo.toml [deleted file]
src/test/rustdoc-gui/src/implementors/lib.rs [deleted file]
src/test/rustdoc-gui/src/lib2/Cargo.lock [new file with mode: 0644]
src/test/rustdoc-gui/src/lib2/Cargo.toml
src/test/rustdoc-gui/src/lib2/implementors/Cargo.lock [new file with mode: 0644]
src/test/rustdoc-gui/src/lib2/implementors/Cargo.toml [new file with mode: 0644]
src/test/rustdoc-gui/src/lib2/implementors/lib.rs [new file with mode: 0644]
src/test/rustdoc-gui/src/lib2/lib.rs
src/test/rustdoc-gui/src/lib2/src/lib.rs [deleted file]
src/test/rustdoc-gui/src/settings/.cargo/config.toml [new file with mode: 0644]
src/test/rustdoc-gui/src/settings/Cargo.lock [new file with mode: 0644]
src/test/rustdoc-gui/src/settings/Cargo.toml [new file with mode: 0644]
src/test/rustdoc-gui/src/settings/lib.rs [new file with mode: 0644]
src/test/rustdoc-gui/src/test_docs/Cargo.lock [new file with mode: 0644]
src/test/rustdoc-ui/unknown-renamed-lints.stderr
src/test/rustdoc/default-theme.rs [new file with mode: 0644]
src/test/rustdoc/toggle-item-contents.rs
src/test/ui-fulldeps/session-derive-errors.stderr
src/test/ui/allocator/not-an-allocator.stderr
src/test/ui/allocator/two-allocators.stderr
src/test/ui/associated-consts/associated-const-array-len.stderr
src/test/ui/associated-consts/associated-const-private-impl.stderr
src/test/ui/associated-consts/issue-63496.stderr
src/test/ui/associated-item/issue-48027.stderr
src/test/ui/associated-type-bounds/duplicate.full_tait.stderr
src/test/ui/associated-type-bounds/duplicate.min_tait.stderr
src/test/ui/associated-type-bounds/duplicate.rs
src/test/ui/associated-type-bounds/dyn-lcsit.rs [deleted file]
src/test/ui/associated-type-bounds/dyn-lcsit.stderr [deleted file]
src/test/ui/associated-type-bounds/lcsit.rs [deleted file]
src/test/ui/associated-type-bounds/lcsit.stderr [deleted file]
src/test/ui/associated-types/associated-types-bound-failure.stderr
src/test/ui/associated-types/associated-types-for-unimpl-trait.stderr
src/test/ui/associated-types/associated-types-no-suitable-bound.stderr
src/test/ui/associated-types/associated-types-no-suitable-supertrait-2.stderr
src/test/ui/associated-types/associated-types-no-suitable-supertrait.stderr
src/test/ui/associated-types/associated-types-projection-to-unrelated-trait-in-method-without-default.stderr
src/test/ui/associated-types/associated-types-unconstrained.stderr
src/test/ui/associated-types/hr-associated-type-projection-1.rs
src/test/ui/associated-types/hr-associated-type-projection-1.stderr
src/test/ui/associated-types/issue-44153.stderr
src/test/ui/async-await/async-fn-path-elision.stderr
src/test/ui/async-await/issue-61076.stderr
src/test/ui/async-await/issue-70594.stderr
src/test/ui/async-await/issue-84841.stderr
src/test/ui/async-await/issues/issue-62009-1.stderr
src/test/ui/async-await/pin-needed-to-poll-2.stderr
src/test/ui/async-await/try-on-option-in-async.stderr
src/test/ui/box/into-boxed-slice-fail.stderr
src/test/ui/chalkify/type_wf.stderr
src/test/ui/closures/issue-41366.stderr
src/test/ui/coherence/coherence-fn-covariant-bound-vs-static.stderr
src/test/ui/const-generics/const_evaluatable_checked/object-safety-err-ret.stderr
src/test/ui/const-generics/dont-evaluate-array-len-on-err-1.stderr
src/test/ui/const-generics/exhaustive-value.full.stderr
src/test/ui/const-generics/exhaustive-value.min.stderr
src/test/ui/const-generics/occurs-check/unused-substs-1.stderr
src/test/ui/consts/offset_ub.rs
src/test/ui/consts/offset_ub.stderr
src/test/ui/custom_test_frameworks/mismatch.stderr
src/test/ui/derives/derive-on-trait-item-or-impl-item.rs
src/test/ui/derives/derive-on-trait-item-or-impl-item.stderr
src/test/ui/derives/derives-span-Clone-enum-struct-variant.stderr
src/test/ui/derives/derives-span-Clone-enum.stderr
src/test/ui/derives/derives-span-Clone-struct.stderr
src/test/ui/derives/derives-span-Clone-tuple-struct.stderr
src/test/ui/derives/derives-span-Debug-enum-struct-variant.stderr
src/test/ui/derives/derives-span-Debug-enum.stderr
src/test/ui/derives/derives-span-Debug-struct.stderr
src/test/ui/derives/derives-span-Debug-tuple-struct.stderr
src/test/ui/derives/derives-span-Default-struct.stderr
src/test/ui/derives/derives-span-Default-tuple-struct.stderr
src/test/ui/derives/derives-span-Eq-enum-struct-variant.stderr
src/test/ui/derives/derives-span-Eq-enum.stderr
src/test/ui/derives/derives-span-Eq-struct.stderr
src/test/ui/derives/derives-span-Eq-tuple-struct.stderr
src/test/ui/derives/derives-span-Hash-enum-struct-variant.stderr
src/test/ui/derives/derives-span-Hash-enum.stderr
src/test/ui/derives/derives-span-Hash-struct.stderr
src/test/ui/derives/derives-span-Hash-tuple-struct.stderr
src/test/ui/derives/derives-span-Ord-enum-struct-variant.stderr
src/test/ui/derives/derives-span-Ord-enum.stderr
src/test/ui/derives/derives-span-Ord-struct.stderr
src/test/ui/derives/derives-span-Ord-tuple-struct.stderr
src/test/ui/derives/derives-span-PartialEq-enum-struct-variant.stderr
src/test/ui/derives/derives-span-PartialEq-enum.stderr
src/test/ui/derives/derives-span-PartialEq-struct.stderr
src/test/ui/derives/derives-span-PartialEq-tuple-struct.stderr
src/test/ui/derives/derives-span-PartialOrd-enum-struct-variant.stderr
src/test/ui/derives/derives-span-PartialOrd-enum.stderr
src/test/ui/derives/derives-span-PartialOrd-struct.stderr
src/test/ui/derives/derives-span-PartialOrd-tuple-struct.stderr
src/test/ui/derives/deriving-copyclone.stderr
src/test/ui/derives/deriving-no-inner-impl-error-message.stderr
src/test/ui/derives/deriving-non-type.rs
src/test/ui/derives/deriving-non-type.stderr
src/test/ui/did_you_mean/issue-39802-show-5-trait-impls.stderr
src/test/ui/entry-point/imported_main_const_fn_item_type_forbidden.rs
src/test/ui/entry-point/imported_main_const_fn_item_type_forbidden.stderr
src/test/ui/error-codes/E0038.stderr
src/test/ui/error-codes/E0283.stderr
src/test/ui/error-codes/E0624.stderr
src/test/ui/error-codes/E0777.stderr
src/test/ui/explore-issue-38412.stderr
src/test/ui/feature-gates/feature-gate-associated_type_bounds.rs
src/test/ui/feature-gates/feature-gate-associated_type_bounds.stderr
src/test/ui/feature-gates/feature-gate-impl_trait_in_bindings.rs [deleted file]
src/test/ui/feature-gates/feature-gate-impl_trait_in_bindings.stderr [deleted file]
src/test/ui/feature-gates/feature-gate-min_type_alias_impl_trait.stderr
src/test/ui/feature-gates/feature-gate-object_safe_for_dispatch.stderr
src/test/ui/feature-gates/feature-gate-optimize_attribute.stderr
src/test/ui/feature-gates/feature-gate-type_alias_impl_trait.rs
src/test/ui/feature-gates/feature-gate-type_alias_impl_trait.stderr
src/test/ui/feature-gates/issue-43106-gating-of-derive.rs
src/test/ui/feature-gates/issue-43106-gating-of-derive.stderr
src/test/ui/ffi_const2.stderr
src/test/ui/fmt/ifmt-unimpl.stderr
src/test/ui/for/for-c-in-str.stderr
src/test/ui/for/for-loop-bogosity.stderr
src/test/ui/generator/layout-error.full_tait.stderr
src/test/ui/generator/layout-error.min_tait.stderr
src/test/ui/generator/layout-error.rs
src/test/ui/generator/metadata-sufficient-for-layout.full_tait.stderr
src/test/ui/generator/metadata-sufficient-for-layout.min_tait.stderr
src/test/ui/generator/metadata-sufficient-for-layout.rs
src/test/ui/generator/yield-outside-generator-issue-78653.stderr
src/test/ui/generic-associated-types/gat-in-trait-path.stderr
src/test/ui/generic-associated-types/impl_bounds.stderr
src/test/ui/generic-associated-types/issue-67510-pass.stderr
src/test/ui/generic-associated-types/issue-78113-lifetime-mismatch-dyn-trait-box.rs [new file with mode: 0644]
src/test/ui/generic-associated-types/issue-78113-lifetime-mismatch-dyn-trait-box.stderr [new file with mode: 0644]
src/test/ui/generic-associated-types/issue-81487.rs [new file with mode: 0644]
src/test/ui/generic-associated-types/trait-objects.stderr
src/test/ui/impl-header-lifetime-elision/path-elided.stderr
src/test/ui/impl-header-lifetime-elision/trait-elided.stderr
src/test/ui/impl-trait/binding-without-value.rs [deleted file]
src/test/ui/impl-trait/binding-without-value.stderr [deleted file]
src/test/ui/impl-trait/bindings-opaque.rs [deleted file]
src/test/ui/impl-trait/bindings-opaque.stderr [deleted file]
src/test/ui/impl-trait/bindings.rs [deleted file]
src/test/ui/impl-trait/bindings.stderr [deleted file]
src/test/ui/impl-trait/bound-normalization-fail.rs
src/test/ui/impl-trait/bound-normalization-fail.stderr
src/test/ui/impl-trait/bound-normalization-pass.default.stderr [deleted file]
src/test/ui/impl-trait/bound-normalization-pass.rs
src/test/ui/impl-trait/bound-normalization-pass.sa.stderr [deleted file]
src/test/ui/impl-trait/impl-trait-in-bindings-issue-73003.rs [deleted file]
src/test/ui/impl-trait/impl-trait-in-bindings-issue-73003.stderr [deleted file]
src/test/ui/impl-trait/impl-trait-in-bindings.rs [deleted file]
src/test/ui/impl-trait/impl-trait-in-bindings.stderr [deleted file]
src/test/ui/impl-trait/issue-57200.rs [deleted file]
src/test/ui/impl-trait/issue-57200.stderr [deleted file]
src/test/ui/impl-trait/issue-57201.rs [deleted file]
src/test/ui/impl-trait/issue-57201.stderr [deleted file]
src/test/ui/impl-trait/issue-60473.rs [deleted file]
src/test/ui/impl-trait/issue-60473.stderr [deleted file]
src/test/ui/impl-trait/issue-67166.rs [deleted file]
src/test/ui/impl-trait/issue-67166.stderr [deleted file]
src/test/ui/impl-trait/issue-69840.rs [deleted file]
src/test/ui/impl-trait/issues/issue-70877.full_tait.stderr
src/test/ui/impl-trait/issues/issue-70877.min_tait.stderr
src/test/ui/impl-trait/issues/issue-70877.rs
src/test/ui/impl-trait/issues/issue-78721.rs [deleted file]
src/test/ui/impl-trait/issues/issue-78721.stderr [deleted file]
src/test/ui/impl-trait/issues/issue-78722.full_tait.stderr
src/test/ui/impl-trait/issues/issue-78722.min_tait.stderr
src/test/ui/impl-trait/issues/issue-78722.rs
src/test/ui/impl-trait/issues/issue-83929-impl-trait-in-generic-default.rs
src/test/ui/impl-trait/issues/issue-83929-impl-trait-in-generic-default.stderr
src/test/ui/impl-trait/must_outlive_least_region_or_bound.nll.stderr
src/test/ui/impl-trait/nested_impl_trait.stderr
src/test/ui/impl-trait/static-return-lifetime-infered.nll.stderr
src/test/ui/impl-trait/where-allowed.rs
src/test/ui/impl-trait/where-allowed.stderr
src/test/ui/inference/cannot-infer-async-enabled-impl-trait-bindings.rs [deleted file]
src/test/ui/inference/cannot-infer-async-enabled-impl-trait-bindings.stderr [deleted file]
src/test/ui/issues/issue-10412.stderr
src/test/ui/issues/issue-12997-2.stderr
src/test/ui/issues/issue-17651.stderr
src/test/ui/issues/issue-18611.stderr
src/test/ui/issues/issue-18959.stderr
src/test/ui/issues/issue-20605.stderr
src/test/ui/issues/issue-21160.stderr
src/test/ui/issues/issue-21202.stderr
src/test/ui/issues/issue-28098.stderr
src/test/ui/issues/issue-29147.stderr
src/test/ui/issues/issue-32709.stderr
src/test/ui/issues/issue-33941.stderr
src/test/ui/issues/issue-34229.stderr
src/test/ui/issues/issue-3763.stderr
src/test/ui/issues/issue-39970.stderr
src/test/ui/issues/issue-43023.rs
src/test/ui/issues/issue-43023.stderr
src/test/ui/issues/issue-43623.stderr
src/test/ui/issues/issue-47715.stderr
src/test/ui/issues/issue-49934.rs
src/test/ui/issues/issue-49934.stderr
src/test/ui/issues/issue-53498.stderr
src/test/ui/issues/issue-58022.stderr
src/test/ui/issues/issue-60283.stderr
src/test/ui/issues/issue-66353.stderr
src/test/ui/issues/issue-72690.stderr
src/test/ui/issues/issue-87199.rs [new file with mode: 0644]
src/test/ui/issues/issue-87199.stderr [new file with mode: 0644]
src/test/ui/iterators/integral.stderr
src/test/ui/iterators/ranges.stderr
src/test/ui/iterators/string.stderr
src/test/ui/lint/cli-lint-override.forbid_warn.stderr [new file with mode: 0644]
src/test/ui/lint/cli-lint-override.force_warn_deny.stderr [new file with mode: 0644]
src/test/ui/lint/cli-lint-override.rs [new file with mode: 0644]
src/test/ui/lint/cli-lint-override.warn_deny.stderr [new file with mode: 0644]
src/test/ui/lint/cli-unknown-force-warn.rs [new file with mode: 0644]
src/test/ui/lint/cli-unknown-force-warn.stderr [new file with mode: 0644]
src/test/ui/lint/force-warn/force-allowed-by-default-lint.rs
src/test/ui/lint/force-warn/force-allowed-by-default-lint.stderr
src/test/ui/lint/force-warn/force-allowed-deny-by-default-lint.rs
src/test/ui/lint/force-warn/force-allowed-deny-by-default-lint.stderr
src/test/ui/lint/force-warn/force-allowed-warning.rs
src/test/ui/lint/force-warn/force-allowed-warning.stderr
src/test/ui/lint/force-warn/force-deny-by-default-lint.rs
src/test/ui/lint/force-warn/force-deny-by-default-lint.stderr
src/test/ui/lint/force-warn/force-lint-allow-all-warnings.rs
src/test/ui/lint/force-warn/force-lint-allow-all-warnings.stderr
src/test/ui/lint/force-warn/force-lint-group-allow-all-warnings.rs
src/test/ui/lint/force-warn/force-lint-group-allow-all-warnings.stderr
src/test/ui/lint/force-warn/force-lint-in-allowed-group.rs
src/test/ui/lint/force-warn/force-lint-in-allowed-group.stderr
src/test/ui/lint/force-warn/force-warn-cap-lints-allow.rs [new file with mode: 0644]
src/test/ui/lint/force-warn/force-warn-cap-lints-allow.stderr [new file with mode: 0644]
src/test/ui/lint/force-warn/force-warn-cap-lints-warn.rs
src/test/ui/lint/force-warn/force-warn-cap-lints-warn.stderr
src/test/ui/lint/force-warn/force-warn-group-allow-warning.rs
src/test/ui/lint/force-warn/force-warn-group-allow-warning.stderr
src/test/ui/lint/force-warn/force-warn-group.rs
src/test/ui/lint/force-warn/force-warn-group.stderr
src/test/ui/lint/force-warn/force-warns-cap-lints-allow.rs [deleted file]
src/test/ui/lint/force-warn/force-warns-cap-lints-allow.stderr [deleted file]
src/test/ui/lint/issue-87274-paren-parent.rs [new file with mode: 0644]
src/test/ui/lint/issue-87274-paren-parent.stderr [new file with mode: 0644]
src/test/ui/lint/lint-unknown-lint.rs
src/test/ui/lint/lint-unknown-lint.stderr
src/test/ui/macros/trace_faulty_macros.rs
src/test/ui/macros/trace_faulty_macros.stderr
src/test/ui/mir/issue-75053.full_tait.stderr
src/test/ui/mir/issue-75053.in_bindings.stderr
src/test/ui/mir/issue-75053.min_tait.stderr
src/test/ui/mir/issue-75053.rs
src/test/ui/on-unimplemented/multiple-impls.stderr
src/test/ui/on-unimplemented/on-impl.stderr
src/test/ui/parser/struct-literal-in-for.stderr
src/test/ui/pattern/issue-71042-opaquely-typed-constant-used-in-pattern.rs [deleted file]
src/test/ui/pattern/issue-71042-opaquely-typed-constant-used-in-pattern.stderr [deleted file]
src/test/ui/privacy/privacy1.stderr
src/test/ui/privacy/private-impl-method.stderr
src/test/ui/privacy/private-method-cross-crate.stderr
src/test/ui/privacy/private-method-inherited.stderr
src/test/ui/privacy/private-method.stderr
src/test/ui/privacy/restricted/test.stderr
src/test/ui/proc-macro/attributes-on-modules-fail.rs
src/test/ui/proc-macro/attributes-on-modules-fail.stderr
src/test/ui/proc-macro/macros-in-extern-derive.rs
src/test/ui/proc-macro/macros-in-extern-derive.stderr
src/test/ui/proc-macro/span-from-proc-macro.stderr
src/test/ui/range/range-1.stderr
src/test/ui/range/range_traits-1.stderr
src/test/ui/rfc-1937-termination-trait/termination-trait-test-wrong-type.stderr
src/test/ui/rfc-2497-if-let-chains/disallowed-positions.stderr
src/test/ui/rfc-2632-const-trait-impl/call-generic-in-impl.rs [new file with mode: 0644]
src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.nll.stderr
src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.nll.stderr
src/test/ui/span/issue-29595.stderr
src/test/ui/static/static-method-privacy.stderr
src/test/ui/structs/struct-path-alias-bounds.stderr
src/test/ui/suggestions/expected-boxed-future-isnt-pinned.stderr
src/test/ui/suggestions/issue-72766.stderr
src/test/ui/suggestions/issue-84973.stderr
src/test/ui/suggestions/lifetimes/trait-object-nested-in-impl-trait.nll.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/object-unsafe-trait-should-use-where-sized.stderr
src/test/ui/suggestions/suggest-change-mut.stderr
src/test/ui/suggestions/suggest-remove-refs-1.stderr
src/test/ui/suggestions/suggest-remove-refs-2.stderr
src/test/ui/suggestions/suggest-remove-refs-3.stderr
src/test/ui/traits/bad-sized.stderr
src/test/ui/traits/bound/on-structs-and-enums-locals.stderr
src/test/ui/traits/bound/on-structs-and-enums-xc1.stderr
src/test/ui/traits/cycle-cache-err-60010.stderr
src/test/ui/traits/inheritance/repeated-supertrait-ambig.stderr
src/test/ui/traits/issue-71136.stderr
src/test/ui/traits/issue-77982.stderr
src/test/ui/traits/issue-79458.stderr
src/test/ui/traits/item-privacy.stderr
src/test/ui/traits/method-private.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/static-method-generic-inference.stderr
src/test/ui/traits/suggest-where-clause.stderr
src/test/ui/trivial-bounds/trivial-bounds-leak.stderr
src/test/ui/try-block/try-block-bad-type.stderr
src/test/ui/try-block/try-block-in-while.stderr
src/test/ui/try-trait/bad-interconversion.stderr
src/test/ui/try-trait/option-to-result.stderr
src/test/ui/try-trait/try-on-option-diagnostics.stderr
src/test/ui/try-trait/try-on-option.stderr
src/test/ui/try-trait/try-operator-on-main.stderr
src/test/ui/type-alias-impl-trait/issue-53096.full_tait.stderr
src/test/ui/type-alias-impl-trait/issue-53096.min_tait.stderr
src/test/ui/type-alias-impl-trait/issue-53096.rs
src/test/ui/type-alias-impl-trait/issue-53678-generator-and-const-fn.full_tait.stderr
src/test/ui/type-alias-impl-trait/issue-53678-generator-and-const-fn.min_tait.stderr
src/test/ui/type-alias-impl-trait/issue-53678-generator-and-const-fn.rs
src/test/ui/type-alias-impl-trait/issue-60371.stderr
src/test/ui/type-alias-impl-trait/issue-60407.full_tait.stderr
src/test/ui/type-alias-impl-trait/issue-60407.min_tait.stderr
src/test/ui/type-alias-impl-trait/issue-60407.rs
src/test/ui/type-alias-impl-trait/issue-65679-inst-opaque-ty-from-val-twice.full_tait.stderr
src/test/ui/type-alias-impl-trait/issue-65679-inst-opaque-ty-from-val-twice.rs
src/test/ui/type-alias-impl-trait/issue-85113.rs [deleted file]
src/test/ui/type-alias-impl-trait/issue-85113.stderr [deleted file]
src/test/ui/type-alias-impl-trait/no_inferrable_concrete_type.full_tait.stderr
src/test/ui/type-alias-impl-trait/no_inferrable_concrete_type.min_tait.stderr
src/test/ui/type-alias-impl-trait/no_inferrable_concrete_type.rs
src/test/ui/type-alias-impl-trait/structural-match-no-leak.full_tait.stderr
src/test/ui/type-alias-impl-trait/structural-match-no-leak.min_tait.stderr
src/test/ui/type-alias-impl-trait/structural-match-no-leak.rs
src/test/ui/type-alias-impl-trait/structural-match.full_tait.stderr
src/test/ui/type-alias-impl-trait/structural-match.min_tait.stderr
src/test/ui/type-alias-impl-trait/structural-match.rs
src/test/ui/type-alias-impl-trait/type-alias-impl-trait-const.full_tait.stderr
src/test/ui/type-alias-impl-trait/type-alias-impl-trait-const.min_tait.stderr
src/test/ui/type-alias-impl-trait/type-alias-impl-trait-const.rs
src/test/ui/type/type-check-defaults.stderr
src/test/ui/type/type-params-in-different-spaces-2.stderr
src/test/ui/ufcs/ufcs-qpath-self-mismatch.stderr
src/test/ui/unevaluated_fixed_size_array_len.stderr
src/test/ui/union/union-derive-eq.mirunsafeck.stderr
src/test/ui/union/union-derive-eq.thirunsafeck.stderr
src/test/ui/union/union-generic.mirunsafeck.stderr
src/test/ui/union/union-generic.thirunsafeck.stderr
src/test/ui/wf/wf-foreign-fn-decl-ret.stderr
src/test/ui/wf/wf-in-fn-arg.stderr
src/test/ui/wf/wf-in-foreign-fn-decls-issue-80468.rs
src/test/ui/wf/wf-in-foreign-fn-decls-issue-80468.stderr
src/test/ui/wf/wf-trait-default-fn-arg.stderr
src/test/ui/wf/wf-trait-fn-arg.stderr
src/test/ui/xc-private-method.stderr
src/test/ui/xc-private-method2.stderr
src/tools/cargo
src/tools/clippy/CHANGELOG.md
src/tools/clippy/clippy_lints/src/assign_ops.rs
src/tools/clippy/clippy_lints/src/eq_op.rs
src/tools/clippy/clippy_lints/src/lib.rs
src/tools/clippy/clippy_lints/src/matches.rs
src/tools/clippy/clippy_lints/src/self_named_constructor.rs [new file with mode: 0644]
src/tools/clippy/clippy_lints/src/suspicious_trait_impl.rs
src/tools/clippy/clippy_lints/src/zero_sized_map_values.rs
src/tools/clippy/clippy_utils/src/higher.rs
src/tools/clippy/clippy_utils/src/lib.rs
src/tools/clippy/clippy_utils/src/sugg.rs
src/tools/clippy/clippy_utils/src/ty.rs
src/tools/clippy/doc/basics.md
src/tools/clippy/rust-toolchain
src/tools/clippy/tests/ui/crashes/ice-6179.rs
src/tools/clippy/tests/ui/crashes/ice-7340.rs [new file with mode: 0644]
src/tools/clippy/tests/ui/crashes/ice-7410.rs [new file with mode: 0644]
src/tools/clippy/tests/ui/issue-7447.rs [new file with mode: 0644]
src/tools/clippy/tests/ui/issue_4266.rs
src/tools/clippy/tests/ui/missing-doc-impl.rs
src/tools/clippy/tests/ui/missing-doc-impl.stderr
src/tools/clippy/tests/ui/missing_const_for_fn/cant_be_const.rs
src/tools/clippy/tests/ui/needless_bool/fixable.fixed
src/tools/clippy/tests/ui/needless_bool/fixable.rs
src/tools/clippy/tests/ui/needless_bool/fixable.stderr
src/tools/clippy/tests/ui/self_named_constructor.rs [new file with mode: 0644]
src/tools/clippy/tests/ui/self_named_constructor.stderr [new file with mode: 0644]
src/tools/clippy/tests/ui/suspicious_arithmetic_impl.stderr
src/tools/clippy/tests/ui/unit_arg.rs
src/tools/clippy/tests/ui/unit_arg.stderr
src/tools/clippy/tests/ui/use_self.fixed
src/tools/clippy/tests/ui/use_self.rs
src/tools/clippy/tests/ui/use_self.stderr
src/tools/miri
src/tools/rust-analyzer

index 753853e6acde40290e09e185f6ca75ea36ebd849..5441542d84e0327e289c0d30aafab75fe8541e22 100644 (file)
@@ -3747,6 +3747,7 @@ dependencies = [
  "rustc_span",
  "rustc_symbol_mangling",
  "rustc_target",
+ "smallvec",
  "tempfile",
  "tracing",
 ]
@@ -5094,14 +5095,6 @@ dependencies = [
  "serde_json",
 ]
 
-[[package]]
-name = "term"
-version = "0.0.0"
-dependencies = [
- "core",
- "std",
-]
-
 [[package]]
 name = "term"
 version = "0.6.1"
@@ -5154,7 +5147,6 @@ dependencies = [
  "panic_unwind",
  "proc_macro",
  "std",
- "term 0.0.0",
 ]
 
 [[package]]
index 4c00a7dc99ea9ddecee65ef54d11e621f01b1900..dedfe45aca49bd807af07a9b573d245375e98bbd 100644 (file)
@@ -40,6 +40,7 @@ members = [
 exclude = [
   "build",
   "compiler/rustc_codegen_cranelift",
+  "src/test/rustdoc-gui",
   # HACK(eddyb) This hardcodes the fact that our CI uses `/checkout/obj`.
   "obj",
   # The `x` binary is a thin wrapper that calls `x.py`, which initializes
index 296766f80191c51ddacda724718e3ce7b89b2b85..87950b44083efb8da969b4857759f4971e8b876d 100644 (file)
@@ -1347,12 +1347,6 @@ pub fn noop_visit_expr<T: MutVisitor>(
         }
         ExprKind::Paren(expr) => {
             vis.visit_expr(expr);
-
-            // Nodes that are equal modulo `Paren` sugar no-ops should have the same IDs.
-            *id = expr.id;
-            vis.visit_span(span);
-            visit_thin_attrs(attrs, vis);
-            return;
         }
         ExprKind::Yield(expr) => {
             visit_opt(expr, |expr| vis.visit_expr(expr));
index 292643d6d7510821cdbf653455290170dda6bd86..9f9d41c3f3d9e8f816d7ad0a99eae3c4abfc2dd9 100644 (file)
@@ -343,9 +343,8 @@ fn lower_item_kind(
                 // opaque type Foo1: Trait
                 let ty = self.lower_ty(
                     ty,
-                    ImplTraitContext::OtherOpaqueTy {
+                    ImplTraitContext::TypeAliasesOpaqueTy {
                         capturable_lifetimes: &mut FxHashSet::default(),
-                        origin: hir::OpaqueTyOrigin::TyAlias,
                     },
                 );
                 let generics = self.lower_generics(gen, ImplTraitContext::disallowed());
@@ -484,17 +483,7 @@ fn lower_const_item(
         span: Span,
         body: Option<&Expr>,
     ) -> (&'hir hir::Ty<'hir>, hir::BodyId) {
-        let mut capturable_lifetimes;
-        let itctx = if self.sess.features_untracked().impl_trait_in_bindings {
-            capturable_lifetimes = FxHashSet::default();
-            ImplTraitContext::OtherOpaqueTy {
-                capturable_lifetimes: &mut capturable_lifetimes,
-                origin: hir::OpaqueTyOrigin::Misc,
-            }
-        } else {
-            ImplTraitContext::Disallowed(ImplTraitPosition::Binding)
-        };
-        let ty = self.lower_ty(ty, itctx);
+        let ty = self.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::Binding));
         (ty, self.lower_const_body(span, body))
     }
 
@@ -926,9 +915,8 @@ fn lower_impl_item(&mut self, i: &AssocItem) -> hir::ImplItem<'hir> {
                     Some(ty) => {
                         let ty = self.lower_ty(
                             ty,
-                            ImplTraitContext::OtherOpaqueTy {
+                            ImplTraitContext::TypeAliasesOpaqueTy {
                                 capturable_lifetimes: &mut FxHashSet::default(),
-                                origin: hir::OpaqueTyOrigin::TyAlias,
                             },
                         );
                         hir::ImplItemKind::TyAlias(ty)
index a8d6a99cbeb4c91007ba4d68991f509c6308e088..d4caba924160088c892f4e487b172ef809bd3a51 100644 (file)
@@ -264,8 +264,8 @@ enum ImplTraitContext<'b, 'a> {
         /// Origin: Either OpaqueTyOrigin::FnReturn or OpaqueTyOrigin::AsyncFn,
         origin: hir::OpaqueTyOrigin,
     },
-    /// Impl trait in type aliases, consts and statics.
-    OtherOpaqueTy {
+    /// Impl trait in type aliases.
+    TypeAliasesOpaqueTy {
         /// Set of lifetimes that this opaque type can capture, if it uses
         /// them. This includes lifetimes bound since we entered this context.
         /// For example:
@@ -280,8 +280,6 @@ enum ImplTraitContext<'b, 'a> {
         // FIXME(impl_trait): but `required_region_bounds` will ICE later
         // anyway.
         capturable_lifetimes: &'b mut FxHashSet<hir::LifetimeName>,
-        /// Origin: Either OpaqueTyOrigin::Misc or OpaqueTyOrigin::Binding,
-        origin: hir::OpaqueTyOrigin,
     },
     /// `impl Trait` is not accepted in this position.
     Disallowed(ImplTraitPosition),
@@ -310,8 +308,8 @@ fn reborrow<'this>(&'this mut self) -> ImplTraitContext<'this, 'a> {
             ReturnPositionOpaqueTy { fn_def_id, origin } => {
                 ReturnPositionOpaqueTy { fn_def_id: *fn_def_id, origin: *origin }
             }
-            OtherOpaqueTy { capturable_lifetimes, origin } => {
-                OtherOpaqueTy { capturable_lifetimes, origin: *origin }
+            TypeAliasesOpaqueTy { capturable_lifetimes } => {
+                TypeAliasesOpaqueTy { capturable_lifetimes }
             }
             Disallowed(pos) => Disallowed(*pos),
         }
@@ -1126,7 +1124,7 @@ fn lower_assoc_ty_constraint(
                     //
                     //     fn foo() -> impl Iterator<Item = impl Debug>
                     ImplTraitContext::ReturnPositionOpaqueTy { .. }
-                    | ImplTraitContext::OtherOpaqueTy { .. } => (true, itctx),
+                    | ImplTraitContext::TypeAliasesOpaqueTy { .. } => (true, itctx),
 
                     // We are in the argument position, but within a dyn type:
                     //
@@ -1150,9 +1148,8 @@ fn lower_assoc_ty_constraint(
                         capturable_lifetimes = FxHashSet::default();
                         (
                             true,
-                            ImplTraitContext::OtherOpaqueTy {
+                            ImplTraitContext::TypeAliasesOpaqueTy {
                                 capturable_lifetimes: &mut capturable_lifetimes,
-                                origin: hir::OpaqueTyOrigin::Misc,
                             },
                         )
                     }
@@ -1416,18 +1413,17 @@ fn lower_ty_direct(&mut self, t: &Ty, mut itctx: ImplTraitContext<'_, 'hir>) ->
                             None,
                             |this| this.lower_param_bounds(bounds, itctx),
                         ),
-                    ImplTraitContext::OtherOpaqueTy { ref capturable_lifetimes, origin } => {
+                    ImplTraitContext::TypeAliasesOpaqueTy { ref capturable_lifetimes } => {
                         // Reset capturable lifetimes, any nested impl trait
                         // types will inherit lifetimes from this opaque type,
                         // so don't need to capture them again.
-                        let nested_itctx = ImplTraitContext::OtherOpaqueTy {
+                        let nested_itctx = ImplTraitContext::TypeAliasesOpaqueTy {
                             capturable_lifetimes: &mut FxHashSet::default(),
-                            origin,
                         };
                         self.lower_opaque_impl_trait(
                             span,
                             None,
-                            origin,
+                            hir::OpaqueTyOrigin::TyAlias,
                             def_node_id,
                             Some(capturable_lifetimes),
                             |this| this.lower_param_bounds(bounds, nested_itctx),
@@ -1464,25 +1460,14 @@ fn lower_ty_direct(&mut self, t: &Ty, mut itctx: ImplTraitContext<'_, 'hir>) ->
                             }),
                         ))
                     }
-                    ImplTraitContext::Disallowed(pos) => {
-                        let allowed_in = if self.sess.features_untracked().impl_trait_in_bindings {
-                            "bindings or function and inherent method return types"
-                        } else {
-                            "function and inherent method return types"
-                        };
+                    ImplTraitContext::Disallowed(_) => {
                         let mut err = struct_span_err!(
                             self.sess,
                             t.span,
                             E0562,
                             "`impl Trait` not allowed outside of {}",
-                            allowed_in,
+                            "function and method return types",
                         );
-                        if pos == ImplTraitPosition::Binding && self.sess.is_nightly_build() {
-                            err.help(
-                                "add `#![feature(impl_trait_in_bindings)]` to the crate \
-                                   attributes to enable",
-                            );
-                        }
                         err.emit();
                         hir::TyKind::Err
                     }
@@ -1767,21 +1752,10 @@ fn visit_lifetime(&mut self, lifetime: &'v hir::Lifetime) {
     }
 
     fn lower_local(&mut self, l: &Local) -> hir::Local<'hir> {
-        let ty = l.ty.as_ref().map(|t| {
-            let mut capturable_lifetimes;
-            self.lower_ty(
-                t,
-                if self.sess.features_untracked().impl_trait_in_bindings {
-                    capturable_lifetimes = FxHashSet::default();
-                    ImplTraitContext::OtherOpaqueTy {
-                        capturable_lifetimes: &mut capturable_lifetimes,
-                        origin: hir::OpaqueTyOrigin::Binding,
-                    }
-                } else {
-                    ImplTraitContext::Disallowed(ImplTraitPosition::Binding)
-                },
-            )
-        });
+        let ty = l
+            .ty
+            .as_ref()
+            .map(|t| self.lower_ty(t, ImplTraitContext::Disallowed(ImplTraitPosition::Binding)));
         let init = l.init.as_ref().map(|e| self.lower_expr(e));
         let hir_id = self.lower_node_id(l.id);
         self.lower_attrs(hir_id, &l.attrs);
@@ -2332,13 +2306,17 @@ fn lower_poly_trait_ref(
                 )),
                 _ => None,
             });
-            if let ImplTraitContext::OtherOpaqueTy { ref mut capturable_lifetimes, .. } = itctx {
+            if let ImplTraitContext::TypeAliasesOpaqueTy { ref mut capturable_lifetimes, .. } =
+                itctx
+            {
                 capturable_lifetimes.extend(lt_def_names.clone());
             }
 
             let res = this.lower_trait_ref(&p.trait_ref, itctx.reborrow());
 
-            if let ImplTraitContext::OtherOpaqueTy { ref mut capturable_lifetimes, .. } = itctx {
+            if let ImplTraitContext::TypeAliasesOpaqueTy { ref mut capturable_lifetimes, .. } =
+                itctx
+            {
                 for param in lt_def_names {
                     capturable_lifetimes.remove(&param);
                 }
index fe9f1fb20f05608fe21bc43ffe957ee80a52d6ea..55173c6f8696e419545ef1e8c9a6d8f2157db138 100644 (file)
@@ -336,6 +336,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                             insertion_sp,
                             suggestion,
                         );
+                        err.note("assuming a `'static` lifetime...");
                         err.emit();
                     }
                     AnonymousLifetimeMode::PassThrough | AnonymousLifetimeMode::ReportError => {
index 60d6bae38b56c89c251913fd2eea4235611d87b6..e0389f448ebf29abf7a48d5bc6bedbfba329fdb7 100644 (file)
@@ -84,8 +84,10 @@ fn report_bad_target(sess: &Session, item: &Annotatable, span: Span) -> bool {
             sess,
             span,
             E0774,
-            "`derive` may only be applied to structs, enums and unions",
+            "`derive` may only be applied to `struct`s, `enum`s and `union`s",
         )
+        .span_label(span, "not applicable here")
+        .span_label(item.span(), "not a `struct`, `enum` or `union`")
         .emit();
     }
     bad_target
@@ -99,6 +101,7 @@ fn report_unexpected_literal(sess: &Session, lit: &ast::Lit) {
         _ => "for example, write `#[derive(Debug)]` for `Debug`".to_string(),
     };
     struct_span_err!(sess, lit.span, E0777, "expected path to a trait, found literal",)
+        .span_label(lit.span, "not a trait")
         .help(&help_msg)
         .emit();
 }
index 90cdd62144d7246d5f5b5226786ea5865113b599..2e5ad66c60bb8778919d1f2429671350ef506125 100644 (file)
@@ -149,11 +149,7 @@ fn process_variant(cx: &mut ExtCtxt<'_>, stmts: &mut Vec<ast::Stmt>, variant: &V
             }
             _ => cx.span_bug(
                 trait_span,
-                &format!(
-                    "unexpected substructure in \
-                                                    shallow `derive({})`",
-                    name
-                ),
+                &format!("unexpected substructure in shallow `derive({})`", name),
             ),
         }
     }
index 6b7d0e1f204b5f0a9712db0f32bc9efa547725ac..00d75be4399649987e9b491aa19fb81cf36e7838 100644 (file)
@@ -72,13 +72,9 @@ pub fn to_path(
     ) -> ast::Path {
         let mut idents = self.path.iter().map(|s| Ident::new(*s, span)).collect();
         let lt = mk_lifetimes(cx, span, &self.lifetime);
-        let tys: Vec<P<ast::Ty>> =
-            self.params.iter().map(|t| t.to_ty(cx, span, self_ty, self_generics)).collect();
-        let params = lt
-            .into_iter()
-            .map(GenericArg::Lifetime)
-            .chain(tys.into_iter().map(GenericArg::Type))
-            .collect();
+        let tys = self.params.iter().map(|t| t.to_ty(cx, span, self_ty, self_generics));
+        let params =
+            lt.into_iter().map(GenericArg::Lifetime).chain(tys.map(GenericArg::Type)).collect();
 
         match self.kind {
             PathKind::Global => cx.path_all(span, true, idents, params),
index 6a6f93d50d364b9a054da86e481dcbc9fb62537d..a11098b11c6ebea80839eebf9f6fe13041ceb964 100644 (file)
@@ -16,6 +16,7 @@ libc = "0.2.50"
 jobserver = "0.1.22"
 tempfile = "3.2"
 pathdiff = "0.2.0"
+smallvec = { version = "1.6.1", features = ["union", "may_dangle"] }
 
 rustc_serialize = { path = "../rustc_serialize" }
 rustc_ast = { path = "../rustc_ast" }
index 25268d9a5552f2aaff924dd359a730ba9dfb0f25..81e905b1b5f578279466d7f28feb5ade52ac7147 100644 (file)
@@ -19,8 +19,9 @@
 use rustc_middle::ich::NodeIdHashingMode;
 use rustc_middle::ty::layout::IntegerExt;
 use rustc_middle::ty::subst::{GenericArgKind, SubstsRef};
-use rustc_middle::ty::{self, AdtDef, Ty, TyCtxt};
+use rustc_middle::ty::{self, AdtDef, ExistentialProjection, Ty, TyCtxt};
 use rustc_target::abi::{Integer, TagEncoding, Variants};
+use smallvec::SmallVec;
 
 use std::fmt::Write;
 
@@ -33,6 +34,8 @@ pub fn compute_debuginfo_type_name<'tcx>(
     t: Ty<'tcx>,
     qualified: bool,
 ) -> String {
+    let _prof = tcx.prof.generic_activity("compute_debuginfo_type_name");
+
     let mut result = String::with_capacity(64);
     let mut visited = FxHashSet::default();
     push_debuginfo_type_name(tcx, t, qualified, &mut result, &mut visited);
@@ -41,7 +44,7 @@ pub fn compute_debuginfo_type_name<'tcx>(
 
 // Pushes the name of the type as it should be stored in debuginfo on the
 // `output` String. See also compute_debuginfo_type_name().
-pub fn push_debuginfo_type_name<'tcx>(
+fn push_debuginfo_type_name<'tcx>(
     tcx: TyCtxt<'tcx>,
     t: Ty<'tcx>,
     qualified: bool,
@@ -84,25 +87,14 @@ pub fn push_debuginfo_type_name<'tcx>(
 
             for component_type in component_types {
                 push_debuginfo_type_name(tcx, component_type.expect_ty(), true, output, visited);
-                output.push(',');
-
-                // Natvis does not always like having spaces between parts of the type name
-                // and this causes issues when we need to write a typename in natvis, for example
-                // as part of a cast like the `HashMap` visualizer does.
-                if !cpp_like_names {
-                    output.push(' ');
-                }
+                push_arg_separator(cpp_like_names, output);
             }
             if !component_types.is_empty() {
-                output.pop();
-
-                if !cpp_like_names {
-                    output.pop();
-                }
+                pop_arg_separator(output);
             }
 
             if cpp_like_names {
-                push_close_angle_bracket(tcx, output);
+                push_close_angle_bracket(cpp_like_names, output);
             } else {
                 output.push(')');
             }
@@ -124,7 +116,7 @@ pub fn push_debuginfo_type_name<'tcx>(
             push_debuginfo_type_name(tcx, inner_type, qualified, output, visited);
 
             if cpp_like_names {
-                push_close_angle_bracket(tcx, output);
+                push_close_angle_bracket(cpp_like_names, output);
             }
         }
         ty::Ref(_, inner_type, mutbl) => {
@@ -150,7 +142,7 @@ pub fn push_debuginfo_type_name<'tcx>(
             push_debuginfo_type_name(tcx, inner_type, qualified, output, visited);
 
             if cpp_like_names && !is_slice_or_str {
-                push_close_angle_bracket(tcx, output);
+                push_close_angle_bracket(cpp_like_names, output);
             }
         }
         ty::Array(inner_type, len) => {
@@ -182,69 +174,97 @@ pub fn push_debuginfo_type_name<'tcx>(
             push_debuginfo_type_name(tcx, inner_type, true, output, visited);
 
             if cpp_like_names {
-                push_close_angle_bracket(tcx, output);
+                push_close_angle_bracket(cpp_like_names, output);
             } else {
                 output.push(']');
             }
         }
         ty::Dynamic(ref trait_data, ..) => {
-            if cpp_like_names {
+            let auto_traits: SmallVec<[DefId; 4]> = trait_data.auto_traits().collect();
+
+            let has_enclosing_parens = if cpp_like_names {
                 output.push_str("dyn$<");
+                false
             } else {
-                output.push_str("dyn ");
-            }
+                if trait_data.len() > 1 && auto_traits.len() != 0 {
+                    // We need enclosing parens because there is more than one trait
+                    output.push_str("(dyn ");
+                    true
+                } else {
+                    output.push_str("dyn ");
+                    false
+                }
+            };
 
             if let Some(principal) = trait_data.principal() {
                 let principal =
                     tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), principal);
                 push_item_name(tcx, principal.def_id, qualified, output);
-                push_generic_params_internal(tcx, principal.substs, output, visited);
-            } else {
-                // The auto traits come ordered by `DefPathHash`, which guarantees stability if the
-                // environment is stable (e.g., incremental builds) but not otherwise (e.g.,
-                // updated compiler version, different target).
-                //
-                // To avoid that causing instabilities in test output, sort the auto-traits
-                // alphabetically.
-                let mut auto_traits: Vec<_> = trait_data
-                    .iter()
-                    .filter_map(|predicate| {
-                        match tcx.normalize_erasing_late_bound_regions(
-                            ty::ParamEnv::reveal_all(),
-                            predicate,
-                        ) {
-                            ty::ExistentialPredicate::AutoTrait(def_id) => {
-                                let mut name = String::new();
-                                push_item_name(tcx, def_id, true, &mut name);
-                                Some(name)
-                            }
-                            _ => None,
-                        }
+                let principal_has_generic_params =
+                    push_generic_params_internal(tcx, principal.substs, output, visited);
+
+                let projection_bounds: SmallVec<[_; 4]> = trait_data
+                    .projection_bounds()
+                    .map(|bound| {
+                        let ExistentialProjection { item_def_id, ty, .. } = bound.skip_binder();
+                        (item_def_id, ty)
                     })
                     .collect();
-                auto_traits.sort();
 
-                for name in auto_traits {
-                    output.push_str(&name);
+                if projection_bounds.len() != 0 {
+                    if principal_has_generic_params {
+                        // push_generic_params_internal() above added a `>` but we actually
+                        // want to add more items to that list, so remove that again.
+                        pop_close_angle_bracket(output);
+                    }
 
-                    if cpp_like_names {
-                        output.push_str(", ");
-                    } else {
-                        output.push_str(" + ");
+                    for (item_def_id, ty) in projection_bounds {
+                        push_arg_separator(cpp_like_names, output);
+
+                        if cpp_like_names {
+                            output.push_str("assoc$<");
+                            push_item_name(tcx, item_def_id, false, output);
+                            push_arg_separator(cpp_like_names, output);
+                            push_debuginfo_type_name(tcx, ty, true, output, visited);
+                            push_close_angle_bracket(cpp_like_names, output);
+                        } else {
+                            push_item_name(tcx, item_def_id, false, output);
+                            output.push('=');
+                            push_debuginfo_type_name(tcx, ty, true, output, visited);
+                        }
                     }
+
+                    push_close_angle_bracket(cpp_like_names, output);
                 }
 
-                // Remove the trailing joining characters. For cpp_like_names
-                // this is `, ` otherwise ` + `.
-                output.pop();
-                output.pop();
-                if !cpp_like_names {
-                    output.pop();
+                if auto_traits.len() != 0 {
+                    push_auto_trait_separator(cpp_like_names, output);
                 }
             }
 
+            if auto_traits.len() != 0 {
+                let mut auto_traits: SmallVec<[String; 4]> = auto_traits
+                    .into_iter()
+                    .map(|def_id| {
+                        let mut name = String::with_capacity(20);
+                        push_item_name(tcx, def_id, true, &mut name);
+                        name
+                    })
+                    .collect();
+                auto_traits.sort_unstable();
+
+                for auto_trait in auto_traits {
+                    output.push_str(&auto_trait);
+                    push_auto_trait_separator(cpp_like_names, output);
+                }
+
+                pop_auto_trait_separator(output);
+            }
+
             if cpp_like_names {
-                push_close_angle_bracket(tcx, output);
+                push_close_angle_bracket(cpp_like_names, output);
+            } else if has_enclosing_parens {
+                output.push(')');
             }
         }
         ty::FnDef(..) | ty::FnPtr(_) => {
@@ -296,10 +316,9 @@ pub fn push_debuginfo_type_name<'tcx>(
             if !sig.inputs().is_empty() {
                 for &parameter_type in sig.inputs() {
                     push_debuginfo_type_name(tcx, parameter_type, true, output, visited);
-                    output.push_str(", ");
+                    push_arg_separator(cpp_like_names, output);
                 }
-                output.pop();
-                output.pop();
+                pop_arg_separator(output);
             }
 
             if sig.c_variadic {
@@ -405,7 +424,25 @@ fn msvc_enum_fallback(
                 output.push_str(&format!(", {}", variant));
             }
         }
-        push_close_angle_bracket(tcx, output);
+        push_close_angle_bracket(true, output);
+    }
+
+    const NON_CPP_AUTO_TRAIT_SEPARATOR: &str = " + ";
+
+    fn push_auto_trait_separator(cpp_like_names: bool, output: &mut String) {
+        if cpp_like_names {
+            push_arg_separator(cpp_like_names, output);
+        } else {
+            output.push_str(NON_CPP_AUTO_TRAIT_SEPARATOR);
+        }
+    }
+
+    fn pop_auto_trait_separator(output: &mut String) {
+        if output.ends_with(NON_CPP_AUTO_TRAIT_SEPARATOR) {
+            output.truncate(output.len() - NON_CPP_AUTO_TRAIT_SEPARATOR.len());
+        } else {
+            pop_arg_separator(output);
+        }
     }
 }
 
@@ -466,13 +503,15 @@ fn push_generic_params_internal<'tcx>(
     substs: SubstsRef<'tcx>,
     output: &mut String,
     visited: &mut FxHashSet<Ty<'tcx>>,
-) {
+) -> bool {
     if substs.non_erasable_generics().next().is_none() {
-        return;
+        return false;
     }
 
     debug_assert_eq!(substs, tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), substs));
 
+    let cpp_like_names = cpp_like_names(tcx);
+
     output.push('<');
 
     for type_parameter in substs.non_erasable_generics() {
@@ -486,13 +525,12 @@ fn push_generic_params_internal<'tcx>(
             other => bug!("Unexpected non-erasable generic: {:?}", other),
         }
 
-        output.push_str(", ");
+        push_arg_separator(cpp_like_names, output);
     }
+    pop_arg_separator(output);
+    push_close_angle_bracket(cpp_like_names, output);
 
-    output.pop();
-    output.pop();
-
-    push_close_angle_bracket(tcx, output);
+    true
 }
 
 fn push_const_param<'tcx>(tcx: TyCtxt<'tcx>, ct: &'tcx ty::Const<'tcx>, output: &mut String) {
@@ -541,20 +579,50 @@ fn push_const_param<'tcx>(tcx: TyCtxt<'tcx>, ct: &'tcx ty::Const<'tcx>, output:
 }
 
 pub fn push_generic_params<'tcx>(tcx: TyCtxt<'tcx>, substs: SubstsRef<'tcx>, output: &mut String) {
+    let _prof = tcx.prof.generic_activity("compute_debuginfo_type_name");
     let mut visited = FxHashSet::default();
     push_generic_params_internal(tcx, substs, output, &mut visited);
 }
 
-fn push_close_angle_bracket<'tcx>(tcx: TyCtxt<'tcx>, output: &mut String) {
+fn push_close_angle_bracket(cpp_like_names: bool, output: &mut String) {
     // MSVC debugger always treats `>>` as a shift, even when parsing templates,
     // so add a space to avoid confusion.
-    if cpp_like_names(tcx) && output.ends_with('>') {
+    if cpp_like_names && output.ends_with('>') {
         output.push(' ')
     };
 
     output.push('>');
 }
 
+fn pop_close_angle_bracket(output: &mut String) {
+    assert!(output.ends_with('>'), "'output' does not end with '>': {}", output);
+    output.pop();
+    if output.ends_with(' ') {
+        output.pop();
+    }
+}
+
+fn push_arg_separator(cpp_like_names: bool, output: &mut String) {
+    // Natvis does not always like having spaces between parts of the type name
+    // and this causes issues when we need to write a typename in natvis, for example
+    // as part of a cast like the `HashMap` visualizer does.
+    if cpp_like_names {
+        output.push(',');
+    } else {
+        output.push_str(", ");
+    };
+}
+
+fn pop_arg_separator(output: &mut String) {
+    if output.ends_with(' ') {
+        output.pop();
+    }
+
+    assert!(output.ends_with(','));
+
+    output.pop();
+}
+
 fn cpp_like_names(tcx: TyCtxt<'_>) -> bool {
     tcx.sess.target.is_like_msvc
 }
index df162f8dce0267456005a54055e3dd31e2127d88..1aa5f9959744d975a15b344f07eadb8fcac0060e 100644 (file)
 E0718: include_str!("./error_codes/E0718.md"),
 E0719: include_str!("./error_codes/E0719.md"),
 E0720: include_str!("./error_codes/E0720.md"),
+E0722: include_str!("./error_codes/E0722.md"),
 E0724: include_str!("./error_codes/E0724.md"),
 E0725: include_str!("./error_codes/E0725.md"),
 E0727: include_str!("./error_codes/E0727.md"),
 E0754: include_str!("./error_codes/E0754.md"),
 E0755: include_str!("./error_codes/E0755.md"),
 E0756: include_str!("./error_codes/E0756.md"),
+E0757: include_str!("./error_codes/E0757.md"),
 E0758: include_str!("./error_codes/E0758.md"),
 E0759: include_str!("./error_codes/E0759.md"),
 E0760: include_str!("./error_codes/E0760.md"),
     E0711, // a feature has been declared with conflicting stability attributes
     E0717, // rustc_promotable without stability attribute
 //  E0721, // `await` keyword
-    E0722, // Malformed `#[optimize]` attribute
 //    E0723, unstable feature in `const` context
     E0726, // non-explicit (not `'_`) elided lifetime in unsupported position
 //  E0738, // Removed; errored on `#[track_caller] fn`s in `extern "Rust" { ... }`.
-    E0757, // `#[ffi_const]` functions cannot be `#[ffi_pure]`
     E0772, // `'static' obligation coming from `impl dyn Trait {}` or `impl Foo for dyn Bar {}`.
 }
diff --git a/compiler/rustc_error_codes/src/error_codes/E0722.md b/compiler/rustc_error_codes/src/error_codes/E0722.md
new file mode 100644 (file)
index 0000000..570717a
--- /dev/null
@@ -0,0 +1,31 @@
+The `optimize` attribute was malformed.
+
+Erroneous code example:
+
+```compile_fail,E0722
+#![feature(optimize_attribute)]
+
+#[optimize(something)] // error: invalid argument
+pub fn something() {}
+```
+
+The `#[optimize]` attribute should be used as follows:
+
+- `#[optimize(size)]` -- instructs the optimization pipeline to generate code
+  that's smaller rather than faster
+
+- `#[optimize(speed)]` -- instructs the optimization pipeline to generate code
+  that's faster rather than smaller
+
+For example:
+
+```
+#![feature(optimize_attribute)]
+
+#[optimize(size)]
+pub fn something() {}
+```
+
+See [RFC 2412] for more details.
+
+[RFC 2412]: https://rust-lang.github.io/rfcs/2412-optimize-attr.html
diff --git a/compiler/rustc_error_codes/src/error_codes/E0757.md b/compiler/rustc_error_codes/src/error_codes/E0757.md
new file mode 100644 (file)
index 0000000..41b06b2
--- /dev/null
@@ -0,0 +1,33 @@
+A function was given both the `ffi_const` and `ffi_pure` attributes.
+
+Erroneous code example:
+
+```compile_fail,E0757
+#![feature(ffi_const, ffi_pure)]
+
+extern "C" {
+    #[ffi_const]
+    #[ffi_pure] // error: `#[ffi_const]` function cannot be `#[ffi_pure]`
+    pub fn square(num: i32) -> i32;
+}
+```
+
+As `ffi_const` provides stronger guarantees than `ffi_pure`, remove the
+`ffi_pure` attribute:
+
+```
+#![feature(ffi_const)]
+
+extern "C" {
+    #[ffi_const]
+    pub fn square(num: i32) -> i32;
+}
+```
+
+You can get more information about `const` and `pure` in the [GCC documentation
+on Common Function Attributes]. The unstable Rust Book has more information
+about [`ffi_const`] and [`ffi_pure`].
+
+[GCC documentation on Common Function Attributes]: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html
+[`ffi_const`]: https://doc.rust-lang.org/nightly/unstable-book/language-features/ffi-const.html
+[`ffi_pure`]: https://doc.rust-lang.org/nightly/unstable-book/language-features/ffi-pure.html
index becc1c6db5bbb9c3337c18dee51a0506d7959784..87272b1605b798ce9bf5678e2b20a815e23ab2ae 100644 (file)
@@ -365,10 +365,7 @@ fn render_multispan_macro_backtrace(&self, span: &mut MultiSpan, always_backtrac
                     continue;
                 }
 
-                if matches!(trace.kind, ExpnKind::Inlined) {
-                    new_labels
-                        .push((trace.call_site, "in the inlined copy of this code".to_string()));
-                } else if always_backtrace {
+                if always_backtrace && !matches!(trace.kind, ExpnKind::Inlined) {
                     new_labels.push((
                         trace.def_site,
                         format!(
@@ -398,13 +395,27 @@ fn render_multispan_macro_backtrace(&self, span: &mut MultiSpan, always_backtrac
                 // and it needs an "in this macro invocation" label to match that.
                 let redundant_span = trace.call_site.contains(sp);
 
-                if !redundant_span && matches!(trace.kind, ExpnKind::Macro(MacroKind::Bang, _))
-                    || always_backtrace
-                {
+                if !redundant_span || always_backtrace {
+                    let msg: Cow<'static, _> = match trace.kind {
+                        ExpnKind::Macro(MacroKind::Attr, _) => {
+                            "this procedural macro expansion".into()
+                        }
+                        ExpnKind::Macro(MacroKind::Derive, _) => {
+                            "this derive macro expansion".into()
+                        }
+                        ExpnKind::Macro(MacroKind::Bang, _) => "this macro invocation".into(),
+                        ExpnKind::Inlined => "the inlined copy of this code".into(),
+                        ExpnKind::Root => "in the crate root".into(),
+                        ExpnKind::AstPass(kind) => kind.descr().into(),
+                        ExpnKind::Desugaring(kind) => {
+                            format!("this {} desugaring", kind.descr()).into()
+                        }
+                    };
                     new_labels.push((
                         trace.call_site,
                         format!(
-                            "in this macro invocation{}",
+                            "in {}{}",
+                            msg,
                             if macro_backtrace.len() > 1 && always_backtrace {
                                 // only specify order when the macro
                                 // backtrace is multiple levels deep
index 15123b5b28d373d15e5ec6de04a9efd713354934..a3e40daf6bf6dccaaf22787394abd7b157a5f6e5 100644 (file)
@@ -455,9 +455,6 @@ pub fn set(&self, features: &mut Features, span: Span) {
     /// Allows non-builtin attributes in inner attribute position.
     (active, custom_inner_attributes, "1.30.0", Some(54726), None),
 
-    /// Allows `impl Trait` in bindings (`let`, `const`, `static`).
-    (incomplete, impl_trait_in_bindings, "1.30.0", Some(63065), None),
-
     /// Allows using `reason` in lint attributes and the `#[expect(lint)]` lint check.
     (active, lint_reasons, "1.31.0", Some(54503), None),
 
index 6d3e2b9c5171366219cb1d904d1288e86349285e..29f4423ec85ac05e7bd7c728fe902087abe00a23 100644 (file)
@@ -148,6 +148,10 @@ macro_rules! declare_features {
     (removed, const_raw_ptr_to_usize_cast, "1.55.0", Some(51910), None,
      Some("at compile-time, pointers do not have an integer value, so these casts cannot be properly supported")),
 
+    /// Allows `impl Trait` in bindings (`let`, `const`, `static`).
+    (removed, impl_trait_in_bindings, "1.55.0", Some(63065), None,
+     Some("the implementation was not maintainable, the feature may get reintroduced once the current refactorings are done")),
+
     // -------------------------------------------------------------------------
     // feature-group-end: removed features
     // -------------------------------------------------------------------------
index 4b2679e164aac6505208cf0427a9d4c49dc55348..6aff2fdbd1f220e6964f2340cc371bfb5ff1bea2 100644 (file)
@@ -2264,18 +2264,14 @@ pub struct OpaqueTy<'hir> {
 }
 
 /// From whence the opaque type came.
-#[derive(Copy, Clone, Encodable, Decodable, Debug, HashStable_Generic)]
+#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, HashStable_Generic)]
 pub enum OpaqueTyOrigin {
     /// `-> impl Trait`
     FnReturn,
     /// `async fn`
     AsyncFn,
-    /// `let _: impl Trait = ...`
-    Binding,
     /// type aliases: `type Foo = impl Trait;`
     TyAlias,
-    /// Impl trait consts, statics, bounds.
-    Misc,
 }
 
 /// The various kinds of types recognized by the compiler.
@@ -3064,6 +3060,27 @@ pub fn hir_id(&self) -> Option<HirId> {
             Node::Crate(_) | Node::Visibility(_) => None,
         }
     }
+
+    /// Returns `Constness::Const` when this node is a const fn/impl.
+    pub fn constness(&self) -> Constness {
+        match self {
+            Node::Item(Item {
+                kind: ItemKind::Fn(FnSig { header: FnHeader { constness, .. }, .. }, ..),
+                ..
+            })
+            | Node::TraitItem(TraitItem {
+                kind: TraitItemKind::Fn(FnSig { header: FnHeader { constness, .. }, .. }, ..),
+                ..
+            })
+            | Node::ImplItem(ImplItem {
+                kind: ImplItemKind::Fn(FnSig { header: FnHeader { constness, .. }, .. }, ..),
+                ..
+            })
+            | Node::Item(Item { kind: ItemKind::Impl(Impl { constness, .. }), .. }) => *constness,
+
+            _ => Constness::NotConst,
+        }
+    }
 }
 
 // Some nodes are used a lot. Make sure they don't unintentionally get bigger.
index ac953f4305c31d3622c9b512715e2d727c925fb3..448dd6623482cf67f6fbddc93c5921a64b4d4d87 100644 (file)
@@ -102,20 +102,11 @@ pub fn canonicalize_user_type_annotation<V>(&self, value: V) -> Canonicalized<'t
         )
     }
 
-    /// A hacky variant of `canonicalize_query` that does not
-    /// canonicalize `'static`. Unfortunately, the existing leak
-    /// check treats `'static` differently in some cases (see also
-    /// #33684), so if we are performing an operation that may need to
-    /// prove "leak-check" related things, we leave `'static`
-    /// alone.
-    ///
-    /// `'static` is also special cased when winnowing candidates when
-    /// selecting implementation candidates, so we also have to leave `'static`
-    /// alone for queries that do selection.
-    //
-    // FIXME(#48536): once the above issues are resolved, we can remove this
-    // and just use `canonicalize_query`.
-    pub fn canonicalize_hr_query_hack<V>(
+    /// A variant of `canonicalize_query` that does not
+    /// canonicalize `'static`. This is useful when
+    /// the query implementation can perform more efficient
+    /// handling of `'static` regions (e.g. trait evaluation).
+    pub fn canonicalize_query_keep_static<V>(
         &self,
         value: V,
         query_state: &mut OriginalQueryValues<'tcx>,
index e3a79fe2653305da6414187b0301b48d9f660ad0..f885c0a4b87bd1f6c42312128203d18381cb6227 100644 (file)
@@ -995,7 +995,7 @@ fn cmp_fn_sig(
         let get_lifetimes = |sig| {
             use rustc_hir::def::Namespace;
             let mut s = String::new();
-            let (_, (sig, reg)) = ty::print::FmtPrinter::new(self.tcx, &mut s, Namespace::TypeNS)
+            let (_, sig, reg) = ty::print::FmtPrinter::new(self.tcx, &mut s, Namespace::TypeNS)
                 .name_all_regions(sig)
                 .unwrap();
             let lts: Vec<String> = reg.into_iter().map(|(_, kind)| kind.to_string()).collect();
@@ -1590,17 +1590,13 @@ enum Mismatch<'a> {
             }
         };
         if let Some((expected, found)) = expected_found {
-            let expected_label = match exp_found {
-                Mismatch::Variable(ef) => ef.expected.prefix_string(self.tcx),
-                Mismatch::Fixed(s) => s.into(),
-            };
-            let found_label = match exp_found {
-                Mismatch::Variable(ef) => ef.found.prefix_string(self.tcx),
-                Mismatch::Fixed(s) => s.into(),
-            };
-            let exp_found = match exp_found {
-                Mismatch::Variable(exp_found) => Some(exp_found),
-                Mismatch::Fixed(_) => None,
+            let (expected_label, found_label, exp_found) = match exp_found {
+                Mismatch::Variable(ef) => (
+                    ef.expected.prefix_string(self.tcx),
+                    ef.found.prefix_string(self.tcx),
+                    Some(ef),
+                ),
+                Mismatch::Fixed(s) => (s.into(), s.into(), None),
             };
             match (&terr, expected == found) {
                 (TypeError::Sorts(values), extra) => {
@@ -2134,7 +2130,7 @@ pub fn construct_generic_bound_failure(
         let new_lt = generics
             .as_ref()
             .and_then(|(parent_g, g)| {
-                let possible: Vec<_> = (b'a'..=b'z').map(|c| format!("'{}", c as char)).collect();
+                let mut possible = (b'a'..=b'z').map(|c| format!("'{}", c as char));
                 let mut lts_names = g
                     .params
                     .iter()
@@ -2150,7 +2146,7 @@ pub fn construct_generic_bound_failure(
                     );
                 }
                 let lts = lts_names.iter().map(|s| -> &str { &*s }).collect::<Vec<_>>();
-                possible.into_iter().find(|candidate| !lts.contains(&candidate.as_str()))
+                possible.find(|candidate| !lts.contains(&candidate.as_str()))
             })
             .unwrap_or("'lt".to_string());
         let add_lt_sugg = generics
index d9a1193aac4bafc0f02516e3480ea48a2f1dd3c1..9a718102cf11d8d225cab04a461eadd1ac2bebae 100644 (file)
@@ -491,11 +491,8 @@ pub fn emit_inference_failure_err(
             span
         };
 
-        let is_named_and_not_impl_trait = |ty: Ty<'_>| {
-            &ty.to_string() != "_" &&
-                // FIXME: Remove this check after `impl_trait_in_bindings` is stabilized. #63527
-                (!ty.is_impl_trait() || self.tcx.features().impl_trait_in_bindings)
-        };
+        let is_named_and_not_impl_trait =
+            |ty: Ty<'_>| &ty.to_string() != "_" && !ty.is_impl_trait();
 
         let ty_msg = match (local_visitor.found_node_ty, local_visitor.found_exact_method_call) {
             (_, Some(_)) => String::new(),
diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mismatched_static_lifetime.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mismatched_static_lifetime.rs
new file mode 100644 (file)
index 0000000..cca1954
--- /dev/null
@@ -0,0 +1,103 @@
+//! Error Reporting for when the lifetime for a type doesn't match the `impl` selected for a predicate
+//! to hold.
+
+use crate::infer::error_reporting::nice_region_error::NiceRegionError;
+use crate::infer::error_reporting::note_and_explain_region;
+use crate::infer::lexical_region_resolve::RegionResolutionError;
+use crate::infer::{SubregionOrigin, TypeTrace};
+use crate::traits::ObligationCauseCode;
+use rustc_data_structures::stable_set::FxHashSet;
+use rustc_errors::{Applicability, ErrorReported};
+use rustc_hir as hir;
+use rustc_hir::intravisit::Visitor;
+use rustc_middle::ty::{self, TypeVisitor};
+use rustc_span::MultiSpan;
+
+impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
+    pub(super) fn try_report_mismatched_static_lifetime(&self) -> Option<ErrorReported> {
+        let error = self.error.as_ref()?;
+        debug!("try_report_mismatched_static_lifetime {:?}", error);
+
+        let (origin, sub, sup) = match error.clone() {
+            RegionResolutionError::ConcreteFailure(origin, sub, sup) => (origin, sub, sup),
+            _ => return None,
+        };
+        if *sub != ty::RegionKind::ReStatic {
+            return None;
+        }
+        let cause = match origin {
+            SubregionOrigin::Subtype(box TypeTrace { ref cause, .. }) => cause,
+            _ => return None,
+        };
+        let (parent, impl_def_id) = match &cause.code {
+            ObligationCauseCode::MatchImpl(parent, impl_def_id) => (parent, impl_def_id),
+            _ => return None,
+        };
+        let binding_span = match **parent {
+            ObligationCauseCode::BindingObligation(_def_id, binding_span) => binding_span,
+            _ => return None,
+        };
+        let mut err = self.tcx().sess.struct_span_err(cause.span, "incompatible lifetime on type");
+        // FIXME: we should point at the lifetime
+        let mut multi_span: MultiSpan = vec![binding_span].into();
+        multi_span
+            .push_span_label(binding_span, "introduces a `'static` lifetime requirement".into());
+        err.span_note(multi_span, "because this has an unmet lifetime requirement");
+        note_and_explain_region(self.tcx(), &mut err, "", sup, "...");
+        if let Some(impl_node) = self.tcx().hir().get_if_local(*impl_def_id) {
+            // If an impl is local, then maybe this isn't what they want. Try to
+            // be as helpful as possible with implicit lifetimes.
+
+            // First, let's get the hir self type of the impl
+            let impl_self_ty = match impl_node {
+                hir::Node::Item(hir::Item {
+                    kind: hir::ItemKind::Impl(hir::Impl { self_ty, .. }),
+                    ..
+                }) => self_ty,
+                _ => bug!("Node not an impl."),
+            };
+
+            // Next, let's figure out the set of trait objects with implict static bounds
+            let ty = self.tcx().type_of(*impl_def_id);
+            let mut v = super::static_impl_trait::TraitObjectVisitor(FxHashSet::default());
+            v.visit_ty(ty);
+            let mut traits = vec![];
+            for matching_def_id in v.0 {
+                let mut hir_v =
+                    super::static_impl_trait::HirTraitObjectVisitor(&mut traits, matching_def_id);
+                hir_v.visit_ty(&impl_self_ty);
+            }
+
+            if traits.is_empty() {
+                // If there are no trait object traits to point at, either because
+                // there aren't trait objects or because none are implicit, then just
+                // write a single note on the impl itself.
+
+                let impl_span = self.tcx().def_span(*impl_def_id);
+                err.span_note(impl_span, "...does not necessarily outlive the static lifetime introduced by the compatible `impl`");
+            } else {
+                // Otherwise, point at all implicit static lifetimes
+
+                err.note("...does not necessarily outlive the static lifetime introduced by the compatible `impl`");
+                for span in &traits {
+                    err.span_note(*span, "this has an implicit `'static` lifetime requirement");
+                    // It would be nice to put this immediately under the above note, but they get
+                    // pushed to the end.
+                    err.span_suggestion_verbose(
+                        span.shrink_to_hi(),
+                        "consider relaxing the implicit `'static` requirement",
+                        " + '_".to_string(),
+                        Applicability::MaybeIncorrect,
+                    );
+                }
+            }
+        } else {
+            // Otherwise just point out the impl.
+
+            let impl_span = self.tcx().def_span(*impl_def_id);
+            err.span_note(impl_span, "...does not necessarily outlive the static lifetime introduced by the compatible `impl`");
+        }
+        err.emit();
+        Some(ErrorReported)
+    }
+}
index e20436690b3aa1d42309ea097afa3fa5bc216218..3f27bf67b59a91d357eb88806d2186b881d49b9b 100644 (file)
@@ -7,6 +7,7 @@
 
 mod different_lifetimes;
 pub mod find_anon_type;
+mod mismatched_static_lifetime;
 mod named_anon_conflict;
 mod placeholder_error;
 mod static_impl_trait;
@@ -58,6 +59,7 @@ pub fn try_report(&self) -> Option<ErrorReported> {
             .or_else(|| self.try_report_impl_not_conforming_to_trait())
             .or_else(|| self.try_report_anon_anon_conflict())
             .or_else(|| self.try_report_static_impl_trait())
+            .or_else(|| self.try_report_mismatched_static_lifetime())
     }
 
     pub fn regions(&self) -> Option<(Span, ty::Region<'tcx>, ty::Region<'tcx>)> {
index 1e926989263c9cb66ea81f0eb7a356a6f6cbd3c4..fde4ec05ffc867f74ec0aeced86aa748bc26d07e 100644 (file)
@@ -4,6 +4,7 @@
 use crate::infer::lexical_region_resolve::RegionResolutionError;
 use crate::infer::{SubregionOrigin, TypeTrace};
 use crate::traits::{ObligationCauseCode, UnifyReceiverContext};
+use rustc_data_structures::stable_set::FxHashSet;
 use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder, ErrorReported};
 use rustc_hir::def_id::DefId;
 use rustc_hir::intravisit::{walk_ty, ErasedMap, NestedVisitorMap, Visitor};
@@ -185,17 +186,20 @@ pub(super) fn try_report_static_impl_trait(&self) -> Option<ErrorReported> {
             }
         }
         if let SubregionOrigin::Subtype(box TypeTrace { cause, .. }) = &sub_origin {
-            if let ObligationCauseCode::ItemObligation(item_def_id) = cause.code {
+            let code = match &cause.code {
+                ObligationCauseCode::MatchImpl(parent, ..) => &**parent,
+                _ => &cause.code,
+            };
+            if let ObligationCauseCode::ItemObligation(item_def_id) = *code {
                 // Same case of `impl Foo for dyn Bar { fn qux(&self) {} }` introducing a `'static`
                 // lifetime as above, but called using a fully-qualified path to the method:
                 // `Foo::qux(bar)`.
-                let mut v = TraitObjectVisitor(vec![]);
+                let mut v = TraitObjectVisitor(FxHashSet::default());
                 v.visit_ty(param.param_ty);
                 if let Some((ident, self_ty)) =
-                    self.get_impl_ident_and_self_ty_from_trait(item_def_id, &v.0[..])
+                    self.get_impl_ident_and_self_ty_from_trait(item_def_id, &v.0)
                 {
-                    if self.suggest_constrain_dyn_trait_in_impl(&mut err, &v.0[..], ident, self_ty)
-                    {
+                    if self.suggest_constrain_dyn_trait_in_impl(&mut err, &v.0, ident, self_ty) {
                         override_error_code = Some(ident);
                     }
                 }
@@ -336,7 +340,7 @@ pub(super) fn try_report_static_impl_trait(&self) -> Option<ErrorReported> {
     fn get_impl_ident_and_self_ty_from_trait(
         &self,
         def_id: DefId,
-        trait_objects: &[DefId],
+        trait_objects: &FxHashSet<DefId>,
     ) -> Option<(Ident, &'tcx hir::Ty<'tcx>)> {
         let tcx = self.tcx();
         match tcx.hir().get_if_local(def_id) {
@@ -373,9 +377,10 @@ fn get_impl_ident_and_self_ty_from_trait(
                                         // multiple `impl`s for the same trait like
                                         // `impl Foo for Box<dyn Bar>` and `impl Foo for dyn Bar`.
                                         // In that case, only the first one will get suggestions.
-                                        let mut hir_v = HirTraitObjectVisitor(vec![], *did);
+                                        let mut traits = vec![];
+                                        let mut hir_v = HirTraitObjectVisitor(&mut traits, *did);
                                         hir_v.visit_ty(self_ty);
-                                        !hir_v.0.is_empty()
+                                        !traits.is_empty()
                                     }) =>
                                     {
                                         Some(self_ty)
@@ -417,33 +422,34 @@ fn find_impl_on_dyn_trait(
             _ => return false,
         };
 
-        let mut v = TraitObjectVisitor(vec![]);
+        let mut v = TraitObjectVisitor(FxHashSet::default());
         v.visit_ty(ty);
 
         // Get the `Ident` of the method being called and the corresponding `impl` (to point at
         // `Bar` in `impl Foo for dyn Bar {}` and the definition of the method being called).
         let (ident, self_ty) =
-            match self.get_impl_ident_and_self_ty_from_trait(instance.def_id(), &v.0[..]) {
+            match self.get_impl_ident_and_self_ty_from_trait(instance.def_id(), &v.0) {
                 Some((ident, self_ty)) => (ident, self_ty),
                 None => return false,
             };
 
         // Find the trait object types in the argument, so we point at *only* the trait object.
-        self.suggest_constrain_dyn_trait_in_impl(err, &v.0[..], ident, self_ty)
+        self.suggest_constrain_dyn_trait_in_impl(err, &v.0, ident, self_ty)
     }
 
     fn suggest_constrain_dyn_trait_in_impl(
         &self,
         err: &mut DiagnosticBuilder<'_>,
-        found_dids: &[DefId],
+        found_dids: &FxHashSet<DefId>,
         ident: Ident,
         self_ty: &hir::Ty<'_>,
     ) -> bool {
         let mut suggested = false;
         for found_did in found_dids {
-            let mut hir_v = HirTraitObjectVisitor(vec![], *found_did);
+            let mut traits = vec![];
+            let mut hir_v = HirTraitObjectVisitor(&mut traits, *found_did);
             hir_v.visit_ty(&self_ty);
-            for span in &hir_v.0 {
+            for span in &traits {
                 let mut multi_span: MultiSpan = vec![*span].into();
                 multi_span.push_span_label(
                     *span,
@@ -468,14 +474,14 @@ fn suggest_constrain_dyn_trait_in_impl(
 }
 
 /// Collect all the trait objects in a type that could have received an implicit `'static` lifetime.
-struct TraitObjectVisitor(Vec<DefId>);
+pub(super) struct TraitObjectVisitor(pub(super) FxHashSet<DefId>);
 
 impl TypeVisitor<'_> for TraitObjectVisitor {
     fn visit_ty(&mut self, t: Ty<'_>) -> ControlFlow<Self::BreakTy> {
         match t.kind() {
             ty::Dynamic(preds, RegionKind::ReStatic) => {
                 if let Some(def_id) = preds.principal_def_id() {
-                    self.0.push(def_id);
+                    self.0.insert(def_id);
                 }
                 ControlFlow::CONTINUE
             }
@@ -485,9 +491,9 @@ fn visit_ty(&mut self, t: Ty<'_>) -> ControlFlow<Self::BreakTy> {
 }
 
 /// Collect all `hir::Ty<'_>` `Span`s for trait objects with an implicit lifetime.
-struct HirTraitObjectVisitor(Vec<Span>, DefId);
+pub(super) struct HirTraitObjectVisitor<'a>(pub(super) &'a mut Vec<Span>, pub(super) DefId);
 
-impl<'tcx> Visitor<'tcx> for HirTraitObjectVisitor {
+impl<'a, 'tcx> Visitor<'tcx> for HirTraitObjectVisitor<'a> {
     type Map = ErasedMap<'tcx>;
 
     fn nested_visit_map(&mut self) -> NestedVisitorMap<Self::Map> {
index b3d7876c6e81922c91e25ea4ea10bd911b2cdd40..4af1bdf97a773f7e9796b857d02ce31ff6f24b32 100644 (file)
@@ -47,16 +47,18 @@ pub struct TypeFreshener<'a, 'tcx> {
     const_freshen_count: u32,
     ty_freshen_map: FxHashMap<ty::InferTy, Ty<'tcx>>,
     const_freshen_map: FxHashMap<ty::InferConst<'tcx>, &'tcx ty::Const<'tcx>>,
+    keep_static: bool,
 }
 
 impl<'a, 'tcx> TypeFreshener<'a, 'tcx> {
-    pub fn new(infcx: &'a InferCtxt<'a, 'tcx>) -> TypeFreshener<'a, 'tcx> {
+    pub fn new(infcx: &'a InferCtxt<'a, 'tcx>, keep_static: bool) -> TypeFreshener<'a, 'tcx> {
         TypeFreshener {
             infcx,
             ty_freshen_count: 0,
             const_freshen_count: 0,
             ty_freshen_map: Default::default(),
             const_freshen_map: Default::default(),
+            keep_static,
         }
     }
 
@@ -124,8 +126,7 @@ fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
                 r
             }
 
-            ty::ReStatic
-            | ty::ReEarlyBound(..)
+            ty::ReEarlyBound(..)
             | ty::ReFree(_)
             | ty::ReVar(_)
             | ty::RePlaceholder(..)
@@ -134,6 +135,13 @@ fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
                 // replace all free regions with 'erased
                 self.tcx().lifetimes.re_erased
             }
+            ty::ReStatic => {
+                if self.keep_static {
+                    r
+                } else {
+                    self.tcx().lifetimes.re_erased
+                }
+            }
         }
     }
 
index ab34cda8cc18f514edec1adcd522ea453b05d3cd..869fd225d5114766625630418f73d2b61023dd1c 100644 (file)
@@ -638,6 +638,7 @@ fn collect_errors(
             let sub = var_data.normalize(self.tcx(), verify.region);
 
             let verify_kind_ty = verify.kind.to_ty(self.tcx());
+            let verify_kind_ty = var_data.normalize(self.tcx(), verify_kind_ty);
             if self.bound_is_met(&verify.bound, var_data, verify_kind_ty, sub) {
                 continue;
             }
index f39431f2494b1868f53c19f58ff893eb0c93a614..d3bfb2b2e4428090a07ea433f4f8de16598929ba 100644 (file)
@@ -646,7 +646,12 @@ pub fn type_var_diverges(&'a self, ty: Ty<'_>) -> bool {
     }
 
     pub fn freshener<'b>(&'b self) -> TypeFreshener<'b, 'tcx> {
-        freshen::TypeFreshener::new(self)
+        freshen::TypeFreshener::new(self, false)
+    }
+
+    /// Like `freshener`, but does not replace `'static` regions.
+    pub fn freshener_keep_static<'b>(&'b self) -> TypeFreshener<'b, 'tcx> {
+        freshen::TypeFreshener::new(self, true)
     }
 
     pub fn type_is_unconstrained_numeric(&'a self, ty: Ty<'_>) -> UnconstrainedNumeric {
index c44df407f6b3ae5ef3c88bc1bada2f2b6f3921af..f448acd24fc551a3e64c0a7fd16f8902ad272f62 100644 (file)
@@ -370,7 +370,7 @@ pub fn check_lint_name_cmdline(
                 match level {
                     Level::Allow => "-A",
                     Level::Warn => "-W",
-                    Level::ForceWarn => "--force-warns",
+                    Level::ForceWarn => "--force-warn",
                     Level::Deny => "-D",
                     Level::Forbid => "-F",
                 },
@@ -481,17 +481,17 @@ pub fn check_lint_name(
 
     fn no_lint_suggestion(&self, lint_name: &str) -> CheckLintNameResult<'_> {
         let name_lower = lint_name.to_lowercase();
-        let symbols =
-            self.get_lints().iter().map(|l| Symbol::intern(&l.name_lower())).collect::<Vec<_>>();
 
         if lint_name.chars().any(char::is_uppercase) && self.find_lints(&name_lower).is_ok() {
             // First check if the lint name is (partly) in upper case instead of lower case...
-            CheckLintNameResult::NoLint(Some(Symbol::intern(&name_lower)))
-        } else {
-            // ...if not, search for lints with a similar name
-            let suggestion = find_best_match_for_name(&symbols, Symbol::intern(&name_lower), None);
-            CheckLintNameResult::NoLint(suggestion)
+            return CheckLintNameResult::NoLint(Some(Symbol::intern(&name_lower)));
         }
+        // ...if not, search for lints with a similar name
+        let groups = self.lint_groups.keys().copied().map(Symbol::intern);
+        let lints = self.lints.iter().map(|l| Symbol::intern(&l.name_lower()));
+        let names: Vec<Symbol> = groups.chain(lints).collect();
+        let suggestion = find_best_match_for_name(&names, Symbol::intern(&name_lower), None);
+        CheckLintNameResult::NoLint(suggestion)
     }
 
     fn check_tool_name_for_backwards_compat(
index bc6956f57978311e02de9344d56f3a9bc404533e..069fa41fa886ab175b09186fbbabe2a70e3e401d 100644 (file)
@@ -26,8 +26,6 @@
 use rustc_span::{source_map::MultiSpan, Span, DUMMY_SP};
 use tracing::debug;
 
-use std::cmp;
-
 fn lint_levels(tcx: TyCtxt<'_>, (): ()) -> LintLevelMap {
     let store = unerased_lint_store(tcx);
     let crate_attrs = tcx.hir().attrs(CRATE_HIR_ID);
@@ -91,12 +89,6 @@ fn process_command_line(&mut self, sess: &Session, store: &LintStore) {
         for &(ref lint_name, level) in &sess.opts.lint_opts {
             store.check_lint_name_cmdline(sess, &lint_name, level, self.crate_attrs);
             let orig_level = level;
-
-            // If the cap is less than this specified level, e.g., if we've got
-            // `--cap-lints allow` but we've also got `-D foo` then we ignore
-            // this specification as the lint cap will set it to allow anyway.
-            let level = cmp::min(level, self.sets.lint_cap);
-
             let lint_flag_val = Symbol::intern(lint_name);
 
             let ids = match store.find_lints(&lint_name) {
@@ -104,23 +96,17 @@ fn process_command_line(&mut self, sess: &Session, store: &LintStore) {
                 Err(_) => continue, // errors handled in check_lint_name_cmdline above
             };
             for id in ids {
+                // ForceWarn and Forbid cannot be overriden
+                if let Some((Level::ForceWarn | Level::Forbid, _)) = specs.get(&id) {
+                    continue;
+                }
+
                 self.check_gated_lint(id, DUMMY_SP);
                 let src = LintLevelSource::CommandLine(lint_flag_val, orig_level);
                 specs.insert(id, (level, src));
             }
         }
 
-        for lint_name in &sess.opts.force_warns {
-            store.check_lint_name_cmdline(sess, lint_name, Level::ForceWarn, self.crate_attrs);
-            let lints = store
-                .find_lints(lint_name)
-                .unwrap_or_else(|_| bug!("A valid lint failed to produce a lint ids"));
-            for id in lints {
-                let src = LintLevelSource::CommandLine(Symbol::intern(lint_name), Level::ForceWarn);
-                specs.insert(id, (Level::ForceWarn, src));
-            }
-        }
-
         self.cur = self.sets.list.push(LintSet { specs, parent: COMMAND_LINE });
     }
 
index 4d85bf6b499d950ca010bc312b95781738615ea8..4190e769976e9bfe374b996959d5295279dddd00 100644 (file)
@@ -64,7 +64,7 @@ pub fn as_str(self) -> &'static str {
         match self {
             Level::Allow => "allow",
             Level::Warn => "warn",
-            Level::ForceWarn => "force-warns",
+            Level::ForceWarn => "force-warn",
             Level::Deny => "deny",
             Level::Forbid => "forbid",
         }
index ae53f1ac3bb49aad914d0da0e5e5804e592720e6..392372fad531ead1f3b8c7164264e56089658d86 100644 (file)
@@ -29,7 +29,10 @@ fn fn_decl<'hir>(node: Node<'hir>) -> Option<&'hir FnDecl<'hir>> {
         Node::Item(Item { kind: ItemKind::Fn(sig, _, _), .. })
         | Node::TraitItem(TraitItem { kind: TraitItemKind::Fn(sig, _), .. })
         | Node::ImplItem(ImplItem { kind: ImplItemKind::Fn(sig, _), .. }) => Some(&sig.decl),
-        Node::Expr(Expr { kind: ExprKind::Closure(_, fn_decl, ..), .. }) => Some(fn_decl),
+        Node::Expr(Expr { kind: ExprKind::Closure(_, fn_decl, ..), .. })
+        | Node::ForeignItem(ForeignItem { kind: ForeignItemKind::Fn(fn_decl, ..), .. }) => {
+            Some(fn_decl)
+        }
         _ => None,
     }
 }
index 848e60fe1342ebcd8c1448d5c08eb5a28a2b00c0..6ad68877235dc7d6453c65be964d44e5b278f05a 100644 (file)
@@ -288,7 +288,7 @@ fn struct_lint_level_impl(
                     Level::Deny => "-D",
                     Level::Forbid => "-F",
                     Level::Allow => "-A",
-                    Level::ForceWarn => "--force-warns",
+                    Level::ForceWarn => "--force-warn",
                 };
                 let hyphen_case_lint_name = name.replace("_", "-");
                 if lint_flag_val.as_str() == name {
index 432d078dc9b05d8488b6a58f16ff82483ebedc85..94ac303b109a52011f576fdc18005eb025a85f48 100644 (file)
@@ -240,12 +240,13 @@ pub enum UndefinedBehaviorInfo<'tcx> {
     /// Dereferencing a dangling pointer after it got freed.
     PointerUseAfterFree(AllocId),
     /// Used a pointer outside the bounds it is valid for.
+    /// (If `ptr_size > 0`, determines the size of the memory range that was expected to be in-bounds.)
     PointerOutOfBounds {
         alloc_id: AllocId,
-        offset: Size,
-        size: Size,
+        alloc_size: Size,
+        ptr_offset: i64,
+        ptr_size: Size,
         msg: CheckInAllocMsg,
-        allocation_size: Size,
     },
     /// Using an integer as a pointer in the wrong way.
     DanglingIntPointer(u64, CheckInAllocMsg),
@@ -318,24 +319,25 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
             PointerUseAfterFree(a) => {
                 write!(f, "pointer to {} was dereferenced after this allocation got freed", a)
             }
-            PointerOutOfBounds { alloc_id, offset, size: Size::ZERO, msg, allocation_size } => {
+            PointerOutOfBounds { alloc_id, alloc_size, ptr_offset, ptr_size: Size::ZERO, msg } => {
                 write!(
                     f,
-                    "{}{} has size {}, so pointer at offset {} is out-of-bounds",
+                    "{}{alloc_id} has size {alloc_size}, so pointer at offset {ptr_offset} is out-of-bounds",
                     msg,
-                    alloc_id,
-                    allocation_size.bytes(),
-                    offset.bytes(),
+                    alloc_id = alloc_id,
+                    alloc_size = alloc_size.bytes(),
+                    ptr_offset = ptr_offset,
                 )
             }
-            PointerOutOfBounds { alloc_id, offset, size, msg, allocation_size } => write!(
+            PointerOutOfBounds { alloc_id, alloc_size, ptr_offset, ptr_size, msg } => write!(
                 f,
-                "{}{} has size {}, so pointer to {} bytes starting at offset {} is out-of-bounds",
+                "{}{alloc_id} has size {alloc_size}, so pointer to {ptr_size} byte{ptr_size_p} starting at offset {ptr_offset} is out-of-bounds",
                 msg,
-                alloc_id,
-                allocation_size.bytes(),
-                size.bytes(),
-                offset.bytes(),
+                alloc_id = alloc_id,
+                alloc_size = alloc_size.bytes(),
+                ptr_size = ptr_size.bytes(),
+                ptr_size_p = pluralize!(ptr_size.bytes()),
+                ptr_offset = ptr_offset,
             ),
             DanglingIntPointer(0, CheckInAllocMsg::InboundsTest) => {
                 write!(f, "null pointer is not a valid pointer for this operation")
index 7e7a7119be6a8144e6c7892fb5a38cb51bc217d8..568b3f252bf5f450efa6c5ea34d4879ed5ef17e5 100644 (file)
@@ -36,6 +36,20 @@ fn machine_isize_max(&self) -> i64 {
         i64::try_from(max_isize_plus_1 - 1).unwrap()
     }
 
+    #[inline]
+    fn machine_usize_to_isize(&self, val: u64) -> i64 {
+        let val = val as i64;
+        // Now clamp 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.
+            let max_usize_plus_1 = 1u128 << self.pointer_size().bits();
+            val - i64::try_from(max_usize_plus_1).unwrap()
+        } else {
+            val
+        }
+    }
+
     /// Helper function: truncate given value-"overflowed flag" pair to pointer size and
     /// update "overflowed flag" if there was an overflow.
     /// This should be called by all the other methods before returning!
index cb99ae19ee72ea65a262fb052ec4341ffedabb2e..0908b6a1763d50c32129019ce2e63435908dadd5 100644 (file)
     /// span) for an *existing* error. Therefore, it is best-effort, and may never handle
     /// all of the cases that the normal `ty::Ty`-based wfcheck does. This is fine,
     /// because the `ty::Ty`-based wfcheck is always run.
-    query diagnostic_hir_wf_check(key: (ty::Predicate<'tcx>, hir::HirId)) -> Option<traits::ObligationCause<'tcx>> {
+    query diagnostic_hir_wf_check(key: (ty::Predicate<'tcx>, traits::WellFormedLoc)) -> Option<traits::ObligationCause<'tcx>> {
         eval_always
         no_hash
         desc { "performing HIR wf-checking for predicate {:?} at item {:?}", key.0, key.1 }
index 221dac9ca035dccb9bb83090aad5fc409507c416..a4a2e824637570b96200cb42163fe7a60a764292 100644 (file)
@@ -16,7 +16,7 @@
 use rustc_data_structures::sync::Lrc;
 use rustc_errors::{Applicability, DiagnosticBuilder};
 use rustc_hir as hir;
-use rustc_hir::def_id::DefId;
+use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_hir::Constness;
 use rustc_span::symbol::Symbol;
 use rustc_span::{Span, DUMMY_SP};
@@ -327,12 +327,37 @@ pub enum ObligationCauseCode<'tcx> {
     /// If `X` is the concrete type of an opaque type `impl Y`, then `X` must implement `Y`
     OpaqueType,
 
-    /// Well-formed checking. If a `HirId` is provided,
-    /// it is used to perform HIR-based wf checking if an error
-    /// occurs, in order to generate a more precise error message.
+    /// Well-formed checking. If a `WellFormedLoc` is provided,
+    /// then it will be used to eprform HIR-based wf checking
+    /// after an error occurs, in order to generate a more precise error span.
     /// This is purely for diagnostic purposes - it is always
-    /// correct to use `MiscObligation` instead
-    WellFormed(Option<hir::HirId>),
+    /// correct to use `MiscObligation` instead, or to specify
+    /// `WellFormed(None)`
+    WellFormed(Option<WellFormedLoc>),
+
+    /// From `match_impl`. The cause for us having to match an impl, and the DefId we are matching against.
+    MatchImpl(Lrc<ObligationCauseCode<'tcx>>, DefId),
+}
+
+/// The 'location' at which we try to perform HIR-based wf checking.
+/// This information is used to obtain an `hir::Ty`, which
+/// we can walk in order to obtain precise spans for any
+/// 'nested' types (e.g. `Foo` in `Option<Foo>`).
+#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, HashStable)]
+pub enum WellFormedLoc {
+    /// Use the type of the provided definition.
+    Ty(LocalDefId),
+    /// Use the type of the parameter of the provided function.
+    /// We cannot use `hir::Param`, since the function may
+    /// not have a body (e.g. a trait method definition)
+    Param {
+        /// The function to lookup the parameter in
+        function: LocalDefId,
+        /// The index of the parameter to use.
+        /// Parameters are indexed from 0, with the return type
+        /// being the last 'parameter'
+        param_idx: u16,
+    },
 }
 
 impl ObligationCauseCode<'_> {
index b84058011066f3acaf71b717598a2eddb38e0dc2..4ce49032398bc7877cc2438953c63fec117cfcfc 100644 (file)
@@ -1682,7 +1682,7 @@ fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
 // This is the impl for `&'a InternalSubsts<'a>`.
 nop_list_lift! {substs; GenericArg<'a> => GenericArg<'tcx>}
 
-CloneLiftImpls! { for<'tcx> { Constness, } }
+CloneLiftImpls! { for<'tcx> { Constness, traits::WellFormedLoc, } }
 
 pub mod tls {
     use super::{ptr_eq, GlobalCtxt, TyCtxt};
index 6dfbd28f7763b7db91a00610dc21d5ef151eb3b3..b5733bd2edc2e0cc29f90f02548d8b185e24d907 100644 (file)
@@ -1776,13 +1776,73 @@ pub fn pretty_print_region(mut self, region: ty::Region<'_>) -> Result<Self, fmt
     }
 }
 
+/// Folds through bound vars and placeholders, naming them
+struct RegionFolder<'a, 'tcx> {
+    tcx: TyCtxt<'tcx>,
+    current_index: ty::DebruijnIndex,
+    region_map: BTreeMap<ty::BoundRegion, ty::Region<'tcx>>,
+    name: &'a mut (dyn FnMut(ty::BoundRegion) -> ty::Region<'tcx> + 'a),
+}
+
+impl<'a, 'tcx> ty::TypeFolder<'tcx> for RegionFolder<'a, 'tcx> {
+    fn tcx<'b>(&'b self) -> TyCtxt<'tcx> {
+        self.tcx
+    }
+
+    fn fold_binder<T: TypeFoldable<'tcx>>(
+        &mut self,
+        t: ty::Binder<'tcx, T>,
+    ) -> ty::Binder<'tcx, T> {
+        self.current_index.shift_in(1);
+        let t = t.super_fold_with(self);
+        self.current_index.shift_out(1);
+        t
+    }
+
+    fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
+        match *t.kind() {
+            _ if t.has_vars_bound_at_or_above(self.current_index) || t.has_placeholders() => {
+                return t.super_fold_with(self);
+            }
+            _ => {}
+        }
+        t
+    }
+
+    fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
+        let name = &mut self.name;
+        let region = match *r {
+            ty::ReLateBound(_, br) => self.region_map.entry(br).or_insert_with(|| name(br)),
+            ty::RePlaceholder(ty::PlaceholderRegion { name: kind, .. }) => {
+                // If this is an anonymous placeholder, don't rename. Otherwise, in some
+                // async fns, we get a `for<'r> Send` bound
+                match kind {
+                    ty::BrAnon(_) | ty::BrEnv => r,
+                    _ => {
+                        // Index doesn't matter, since this is just for naming and these never get bound
+                        let br = ty::BoundRegion { var: ty::BoundVar::from_u32(0), kind };
+                        self.region_map.entry(br).or_insert_with(|| name(br))
+                    }
+                }
+            }
+            _ => return r,
+        };
+        if let ty::ReLateBound(debruijn1, br) = *region {
+            assert_eq!(debruijn1, ty::INNERMOST);
+            self.tcx.mk_region(ty::ReLateBound(self.current_index, br))
+        } else {
+            region
+        }
+    }
+}
+
 // HACK(eddyb) limited to `FmtPrinter` because of `binder_depth`,
 // `region_index` and `used_region_names`.
 impl<F: fmt::Write> FmtPrinter<'_, 'tcx, F> {
     pub fn name_all_regions<T>(
         mut self,
         value: &ty::Binder<'tcx, T>,
-    ) -> Result<(Self, (T, BTreeMap<ty::BoundRegion, ty::Region<'tcx>>)), fmt::Error>
+    ) -> Result<(Self, T, BTreeMap<ty::BoundRegion, ty::Region<'tcx>>), fmt::Error>
     where
         T: Print<'tcx, Self, Output = Self, Error = fmt::Error> + TypeFoldable<'tcx>,
     {
@@ -1805,16 +1865,16 @@ fn name_by_region_index(index: usize) -> Symbol {
 
         let mut empty = true;
         let mut start_or_continue = |cx: &mut Self, start: &str, cont: &str| {
-            write!(
-                cx,
-                "{}",
-                if empty {
-                    empty = false;
-                    start
-                } else {
-                    cont
-                }
-            )
+            let w = if empty {
+                empty = false;
+                start
+            } else {
+                cont
+            };
+            let _ = write!(cx, "{}", w);
+        };
+        let do_continue = |cx: &mut Self, cont: Symbol| {
+            let _ = write!(cx, "{}", cont);
         };
 
         define_scoped_cx!(self);
@@ -1824,18 +1884,18 @@ fn name_by_region_index(index: usize) -> Symbol {
         // aren't named. Eventually, we might just want this as the default, but
         // this is not *quite* right and changes the ordering of some output
         // anyways.
-        let new_value = if self.tcx().sess.verbose() {
+        let (new_value, map) = if self.tcx().sess.verbose() {
             // anon index + 1 (BrEnv takes 0) -> name
             let mut region_map: BTreeMap<u32, Symbol> = BTreeMap::default();
             let bound_vars = value.bound_vars();
             for var in bound_vars {
                 match var {
                     ty::BoundVariableKind::Region(ty::BrNamed(_, name)) => {
-                        let _ = start_or_continue(&mut self, "for<", ", ");
-                        let _ = write!(self, "{}", name);
+                        start_or_continue(&mut self, "for<", ", ");
+                        do_continue(&mut self, name);
                     }
                     ty::BoundVariableKind::Region(ty::BrAnon(i)) => {
-                        let _ = start_or_continue(&mut self, "for<", ", ");
+                        start_or_continue(&mut self, "for<", ", ");
                         let name = loop {
                             let name = name_by_region_index(region_index);
                             region_index += 1;
@@ -1843,11 +1903,11 @@ fn name_by_region_index(index: usize) -> Symbol {
                                 break name;
                             }
                         };
-                        let _ = write!(self, "{}", name);
+                        do_continue(&mut self, name);
                         region_map.insert(i + 1, name);
                     }
                     ty::BoundVariableKind::Region(ty::BrEnv) => {
-                        let _ = start_or_continue(&mut self, "for<", ", ");
+                        start_or_continue(&mut self, "for<", ", ");
                         let name = loop {
                             let name = name_by_region_index(region_index);
                             region_index += 1;
@@ -1855,13 +1915,13 @@ fn name_by_region_index(index: usize) -> Symbol {
                                 break name;
                             }
                         };
-                        let _ = write!(self, "{}", name);
+                        do_continue(&mut self, name);
                         region_map.insert(0, name);
                     }
                     _ => continue,
                 }
             }
-            start_or_continue(&mut self, "", "> ")?;
+            start_or_continue(&mut self, "", "> ");
 
             self.tcx.replace_late_bound_regions(value.clone(), |br| {
                 let kind = match br.kind {
@@ -1881,11 +1941,12 @@ fn name_by_region_index(index: usize) -> Symbol {
                 ))
             })
         } else {
-            let new_value = self.tcx.replace_late_bound_regions(value.clone(), |br| {
-                let _ = start_or_continue(&mut self, "for<", ", ");
+            let tcx = self.tcx;
+            let mut name = |br: ty::BoundRegion| {
+                start_or_continue(&mut self, "for<", ", ");
                 let kind = match br.kind {
                     ty::BrNamed(_, name) => {
-                        let _ = write!(self, "{}", name);
+                        do_continue(&mut self, name);
                         br.kind
                     }
                     ty::BrAnon(_) | ty::BrEnv => {
@@ -1896,22 +1957,27 @@ fn name_by_region_index(index: usize) -> Symbol {
                                 break name;
                             }
                         };
-                        let _ = write!(self, "{}", name);
+                        do_continue(&mut self, name);
                         ty::BrNamed(DefId::local(CRATE_DEF_INDEX), name)
                     }
                 };
-                self.tcx.mk_region(ty::ReLateBound(
-                    ty::INNERMOST,
-                    ty::BoundRegion { var: br.var, kind },
-                ))
-            });
-            start_or_continue(&mut self, "", "> ")?;
-            new_value
+                tcx.mk_region(ty::ReLateBound(ty::INNERMOST, ty::BoundRegion { var: br.var, kind }))
+            };
+            let mut folder = RegionFolder {
+                tcx,
+                current_index: ty::INNERMOST,
+                name: &mut name,
+                region_map: BTreeMap::new(),
+            };
+            let new_value = value.clone().skip_binder().fold_with(&mut folder);
+            let region_map = folder.region_map;
+            start_or_continue(&mut self, "", "> ");
+            (new_value, region_map)
         };
 
         self.binder_depth += 1;
         self.region_index = region_index;
-        Ok((self, new_value))
+        Ok((self, new_value, map))
     }
 
     pub fn pretty_in_binder<T>(self, value: &ty::Binder<'tcx, T>) -> Result<Self, fmt::Error>
@@ -1919,8 +1985,8 @@ pub fn pretty_in_binder<T>(self, value: &ty::Binder<'tcx, T>) -> Result<Self, fm
         T: Print<'tcx, Self, Output = Self, Error = fmt::Error> + TypeFoldable<'tcx>,
     {
         let old_region_index = self.region_index;
-        let (new, new_value) = self.name_all_regions(value)?;
-        let mut inner = new_value.0.print(new)?;
+        let (new, new_value, _) = self.name_all_regions(value)?;
+        let mut inner = new_value.print(new)?;
         inner.region_index = old_region_index;
         inner.binder_depth -= 1;
         Ok(inner)
@@ -1935,8 +2001,8 @@ pub fn pretty_wrap_binder<T, C: Fn(&T, Self) -> Result<Self, fmt::Error>>(
         T: Print<'tcx, Self, Output = Self, Error = fmt::Error> + TypeFoldable<'tcx>,
     {
         let old_region_index = self.region_index;
-        let (new, new_value) = self.name_all_regions(value)?;
-        let mut inner = f(&new_value.0, new)?;
+        let (new, new_value, _) = self.name_all_regions(value)?;
+        let mut inner = f(&new_value, new)?;
         inner.region_index = old_region_index;
         inner.binder_depth -= 1;
         Ok(inner)
@@ -1960,6 +2026,12 @@ fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow<Self::BreakTy> {
                 debug!("LateBoundRegionNameCollector::visit_region(r: {:?}, address: {:p})", r, &r);
                 if let ty::ReLateBound(_, ty::BoundRegion { kind: ty::BrNamed(_, name), .. }) = *r {
                     self.used_region_names.insert(name);
+                } else if let ty::RePlaceholder(ty::PlaceholderRegion {
+                    name: ty::BrNamed(_, name),
+                    ..
+                }) = *r
+                {
+                    self.used_region_names.insert(name);
                 }
                 r.super_visit_with(self)
             }
index feb7672f650ecdd1338e55b04693bd211db9d2b8..1460c2378d1c9bfd6b874edcfce93d92f12e2457 100644 (file)
@@ -9,7 +9,7 @@
 use rustc_middle::ty::subst::Subst;
 use rustc_middle::ty::{self, RegionVid, Ty};
 use rustc_span::symbol::{kw, sym};
-use rustc_span::Span;
+use rustc_span::{BytePos, Span};
 
 use crate::util::borrowck_errors;
 
@@ -641,12 +641,14 @@ fn add_static_impl_trait_suggestion(
                         } else {
                             "'_".to_string()
                         };
-                        let suggestion = if snippet.ends_with(';') {
+                        let span = if snippet.ends_with(';') {
                             // `type X = impl Trait;`
-                            format!("{} + {};", &snippet[..snippet.len() - 1], suggestable_fr_name)
+                            span.with_hi(span.hi() - BytePos(1))
                         } else {
-                            format!("{} + {}", snippet, suggestable_fr_name)
+                            span
                         };
+                        let suggestion = format!(" + {}", suggestable_fr_name);
+                        let span = span.shrink_to_hi();
                         diag.span_suggestion(
                             span,
                             &format!(
index baaf6f27ee821377069a336a1e6532723b16d209..2e2578df01146aca4fce8335ac4dc3bd10e58be3 100644 (file)
@@ -1,5 +1,4 @@
 use rustc_data_structures::fx::FxHashMap;
-use rustc_hir::def_id::DefId;
 use rustc_index::vec::IndexVec;
 use rustc_middle::infer::MemberConstraint;
 use rustc_middle::ty::{self, Ty};
@@ -32,9 +31,6 @@
 crate struct NllMemberConstraint<'tcx> {
     next_constraint: Option<NllMemberConstraintIndex>,
 
-    /// The opaque type whose hidden type is being inferred. (Used in error reporting.)
-    crate opaque_type_def_id: DefId,
-
     /// The span where the hidden type was instantiated.
     crate definition_span: Span,
 
@@ -91,7 +87,6 @@ impl<'tcx> MemberConstraintSet<'tcx, ty::RegionVid> {
         let constraint_index = self.constraints.push(NllMemberConstraint {
             next_constraint,
             member_region_vid,
-            opaque_type_def_id: m_c.opaque_type_def_id,
             definition_span: m_c.definition_span,
             hidden_ty: m_c.hidden_ty,
             start_index,
index 0306782bfe442ec14124a56f75dc2d84623f2781..c40e6bf1ec33b8f6b4cae993d9828ce6910a0cc1 100644 (file)
@@ -551,7 +551,7 @@ pub(super) fn solve(
         polonius_output: Option<Rc<PoloniusOutput>>,
     ) -> (Option<ClosureRegionRequirements<'tcx>>, RegionErrors<'tcx>) {
         let mir_def_id = body.source.def_id();
-        self.propagate_constraints(body, infcx.tcx);
+        self.propagate_constraints(body);
 
         let mut errors_buffer = RegionErrors::new();
 
@@ -599,7 +599,7 @@ pub(super) fn solve(
     /// for each region variable until all the constraints are
     /// satisfied. Note that some values may grow **too** large to be
     /// feasible, but we check this later.
-    fn propagate_constraints(&mut self, _body: &Body<'tcx>, tcx: TyCtxt<'tcx>) {
+    fn propagate_constraints(&mut self, _body: &Body<'tcx>) {
         debug!("propagate_constraints()");
 
         debug!("propagate_constraints: constraints={:#?}", {
@@ -617,7 +617,7 @@ fn propagate_constraints(&mut self, _body: &Body<'tcx>, tcx: TyCtxt<'tcx>) {
         // own.
         let constraint_sccs = self.constraint_sccs.clone();
         for scc in constraint_sccs.all_sccs() {
-            self.compute_value_for_scc(scc, tcx);
+            self.compute_value_for_scc(scc);
         }
 
         // Sort the applied member constraints so we can binary search
@@ -629,7 +629,7 @@ fn propagate_constraints(&mut self, _body: &Body<'tcx>, tcx: TyCtxt<'tcx>) {
     /// computed, by unioning the values of its successors.
     /// Assumes that all successors have been computed already
     /// (which is assured by iterating over SCCs in dependency order).
-    fn compute_value_for_scc(&mut self, scc_a: ConstraintSccIndex, tcx: TyCtxt<'tcx>) {
+    fn compute_value_for_scc(&mut self, scc_a: ConstraintSccIndex) {
         let constraint_sccs = self.constraint_sccs.clone();
 
         // Walk each SCC `B` such that `A: B`...
@@ -652,12 +652,7 @@ fn compute_value_for_scc(&mut self, scc_a: ConstraintSccIndex, tcx: TyCtxt<'tcx>
         // Now take member constraints into account.
         let member_constraints = self.member_constraints.clone();
         for m_c_i in member_constraints.indices(scc_a) {
-            self.apply_member_constraint(
-                tcx,
-                scc_a,
-                m_c_i,
-                member_constraints.choice_regions(m_c_i),
-            );
+            self.apply_member_constraint(scc_a, m_c_i, member_constraints.choice_regions(m_c_i));
         }
 
         debug!(
@@ -680,31 +675,12 @@ fn compute_value_for_scc(&mut self, scc_a: ConstraintSccIndex, tcx: TyCtxt<'tcx>
     /// If we make any changes, returns true, else false.
     fn apply_member_constraint(
         &mut self,
-        tcx: TyCtxt<'tcx>,
         scc: ConstraintSccIndex,
         member_constraint_index: NllMemberConstraintIndex,
         choice_regions: &[ty::RegionVid],
     ) -> bool {
         debug!("apply_member_constraint(scc={:?}, choice_regions={:#?})", scc, choice_regions,);
 
-        if let Some(uh_oh) =
-            choice_regions.iter().find(|&&r| !self.universal_regions.is_universal_region(r))
-        {
-            // FIXME(#61773): This case can only occur with
-            // `impl_trait_in_bindings`, I believe, and we are just
-            // opting not to handle it for now. See #61773 for
-            // details.
-            tcx.sess.delay_span_bug(
-                self.member_constraints[member_constraint_index].definition_span,
-                &format!(
-                    "member constraint for `{:?}` has an option region `{:?}` \
-                     that is not a universal region",
-                    self.member_constraints[member_constraint_index].opaque_type_def_id, uh_oh,
-                ),
-            );
-            return false;
-        }
-
         // Create a mutable vector of the options. We'll try to winnow
         // them down.
         let mut choice_regions: Vec<ty::RegionVid> = choice_regions.to_vec();
index 1bb447d1057815e7764d9342d2f56311813e506e..37e0643228acc5c386ab545922bf0d82a43e46ae 100644 (file)
@@ -122,7 +122,6 @@ pub(super) fn equate_inputs_and_outputs(
         if let Err(terr) = self.eq_opaque_type_and_type(
             mir_output_ty,
             normalized_output_ty,
-            mir_def_id,
             Locations::All(output_span),
             ConstraintCategory::BoringNoLocation,
         ) {
@@ -145,7 +144,6 @@ pub(super) fn equate_inputs_and_outputs(
             if let Err(err) = self.eq_opaque_type_and_type(
                 mir_output_ty,
                 user_provided_output_ty,
-                mir_def_id,
                 Locations::All(output_span),
                 ConstraintCategory::BoringNoLocation,
             ) {
index b4fe3313e8a1ed15e9ca2eb7a17092f584dfe728..aa3ff98f7ff9f7439683a81da5ae9e6ae3cee89a 100644 (file)
@@ -1119,6 +1119,7 @@ fn relate_types(
         )
     }
 
+    /// Try to relate `sub <: sup`
     fn sub_types(
         &mut self,
         sub: Ty<'tcx>,
@@ -1129,32 +1130,6 @@ fn sub_types(
         self.relate_types(sub, ty::Variance::Covariant, sup, locations, category)
     }
 
-    /// Try to relate `sub <: sup`; if this fails, instantiate opaque
-    /// variables in `sub` with their inferred definitions and try
-    /// again. This is used for opaque types in places (e.g., `let x:
-    /// impl Foo = ..`).
-    fn sub_types_or_anon(
-        &mut self,
-        sub: Ty<'tcx>,
-        sup: Ty<'tcx>,
-        locations: Locations,
-        category: ConstraintCategory,
-    ) -> Fallible<()> {
-        if let Err(terr) = self.sub_types(sub, sup, locations, category) {
-            if let ty::Opaque(..) = sup.kind() {
-                // When you have `let x: impl Foo = ...` in a closure,
-                // the resulting inferend values are stored with the
-                // def-id of the base function.
-                let parent_def_id =
-                    self.tcx().closure_base_def_id(self.body.source.def_id()).expect_local();
-                return self.eq_opaque_type_and_type(sub, sup, parent_def_id, locations, category);
-            } else {
-                return Err(terr);
-            }
-        }
-        Ok(())
-    }
-
     fn eq_types(
         &mut self,
         a: Ty<'tcx>,
@@ -1207,7 +1182,7 @@ fn relate_type_and_user_type(
     }
 
     /// Equates a type `anon_ty` that may contain opaque types whose
-    /// values are to be inferred by the MIR with def-id `anon_owner_def_id`.
+    /// values are to be inferred by the MIR.
     ///
     /// The type `revealed_ty` contains the same type as `anon_ty`, but with the
     /// hidden types for impl traits revealed.
@@ -1235,12 +1210,10 @@ fn relate_type_and_user_type(
     ///   generics of `foo`). Note that `anon_ty` is not just the opaque type,
     ///   but the entire return type (which may contain opaque types within it).
     /// * `revealed_ty` would be `Box<(T, u32)>`
-    /// * `anon_owner_def_id` would be the def-id of `foo`
     fn eq_opaque_type_and_type(
         &mut self,
         revealed_ty: Ty<'tcx>,
         anon_ty: Ty<'tcx>,
-        anon_owner_def_id: LocalDefId,
         locations: Locations,
         category: ConstraintCategory,
     ) -> Fallible<()> {
@@ -1270,12 +1243,13 @@ fn eq_opaque_type_and_type(
         let tcx = infcx.tcx;
         let param_env = self.param_env;
         let body = self.body;
+        let mir_def_id = body.source.def_id().expect_local();
 
         // the "concrete opaque types" maps
-        let concrete_opaque_types = &tcx.typeck(anon_owner_def_id).concrete_opaque_types;
+        let concrete_opaque_types = &tcx.typeck(mir_def_id).concrete_opaque_types;
         let mut opaque_type_values = VecMap::new();
 
-        debug!("eq_opaque_type_and_type: mir_def_id={:?}", body.source.def_id());
+        debug!("eq_opaque_type_and_type: mir_def_id={:?}", mir_def_id);
         let opaque_type_map = self.fully_perform_op(
             locations,
             category,
@@ -1293,7 +1267,7 @@ fn eq_opaque_type_and_type(
                     // any generic parameters.)
                     let (output_ty, opaque_type_map) =
                         obligations.add(infcx.instantiate_opaque_types(
-                            anon_owner_def_id,
+                            mir_def_id,
                             dummy_body_id,
                             param_env,
                             anon_ty,
@@ -1489,7 +1463,7 @@ fn check_stmt(&mut self, body: &Body<'tcx>, stmt: &Statement<'tcx>, location: Lo
                 let rv_ty = rv.ty(body, tcx);
                 let rv_ty = self.normalize(rv_ty, location);
                 if let Err(terr) =
-                    self.sub_types_or_anon(rv_ty, place_ty, location.to_locations(), category)
+                    self.sub_types(rv_ty, place_ty, location.to_locations(), category)
                 {
                     span_mirbug!(
                         self,
@@ -1776,9 +1750,7 @@ fn check_call_dest(
 
                 let locations = term_location.to_locations();
 
-                if let Err(terr) =
-                    self.sub_types_or_anon(sig.output(), dest_ty, locations, category)
-                {
+                if let Err(terr) = self.sub_types(sig.output(), dest_ty, locations, category) {
                     span_mirbug!(
                         self,
                         term,
index d145ad734cf7aeb011252a31e2903cdfcad16048..6dcd944a1c3f22cc7645704784c76d9b1184a771 100644 (file)
@@ -372,7 +372,7 @@ fn get_ptr_access(
         )
     }
 
-    /// Check if the given pointerpoints to live memory of given `size` and `align`
+    /// Check if the given pointer points to live memory of given `size` and `align`
     /// (ignoring `M::enforce_alignment`). The caller can control the error message for the
     /// out-of-bounds case.
     #[inline(always)]
@@ -451,11 +451,17 @@ fn check_offset_align(offset: u64, align: Align) -> InterpResult<'static> {
                 None
             }
             Ok((alloc_id, offset, ptr)) => {
-                let (allocation_size, alloc_align, ret_val) = alloc_size(alloc_id, offset, ptr)?;
+                let (alloc_size, alloc_align, ret_val) = alloc_size(alloc_id, offset, ptr)?;
                 // Test bounds. This also ensures non-null.
                 // It is sufficient to check this for the end pointer. Also check for overflow!
-                if offset.checked_add(size, &self.tcx).map_or(true, |end| end > allocation_size) {
-                    throw_ub!(PointerOutOfBounds { alloc_id, offset, size, allocation_size, msg })
+                if offset.checked_add(size, &self.tcx).map_or(true, |end| end > alloc_size) {
+                    throw_ub!(PointerOutOfBounds {
+                        alloc_id,
+                        alloc_size,
+                        ptr_offset: self.machine_usize_to_isize(offset.bytes()),
+                        ptr_size: size,
+                        msg,
+                    })
                 }
                 // Test align. Check this last; if both bounds and alignment are violated
                 // we want the error to be about the bounds.
index 646ae8ced7eb442398cee5b2a3808cb8c5567a86..cfc538ef500a12d2e43d4846dc8d46ca23c037b7 100644 (file)
@@ -897,16 +897,19 @@ fn visit_terminator(&mut self, terminator: &Terminator<'tcx>, location: Location
                                 permitted = true;
                             }
                         }
-                        let mut const_impls = true;
-                        tcx.for_each_relevant_impl(trait_id, substs.type_at(0), |imp| {
-                            if const_impls {
-                                if let hir::Constness::NotConst = tcx.impl_constness(imp) {
-                                    const_impls = false;
+                        if !permitted {
+                            // if trait's impls are all const, permit the call.
+                            let mut const_impls = true;
+                            tcx.for_each_relevant_impl(trait_id, substs.type_at(0), |imp| {
+                                if const_impls {
+                                    if let hir::Constness::NotConst = tcx.impl_constness(imp) {
+                                        const_impls = false;
+                                    }
                                 }
+                            });
+                            if const_impls {
+                                permitted = true;
                             }
-                        });
-                        if const_impls {
-                            permitted = true;
                         }
                     }
 
index 3859b22223c006bfc39d2d85282e0518efcbff74..926bd830da0ac470afcf1d1661569da560b1b789 100644 (file)
@@ -133,9 +133,6 @@ fn search_for_structural_match_violation(&self, ty: Ty<'tcx>) -> Option<String>
                     traits::NonStructuralMatchTy::Generator => {
                         "generators cannot be used in patterns".to_string()
                     }
-                    traits::NonStructuralMatchTy::Closure => {
-                        "closures cannot be used in patterns".to_string()
-                    }
                     traits::NonStructuralMatchTy::Param => {
                         bug!("use of a constant whose type is a parameter inside a pattern")
                     }
index 1993e0a602fa50a0e57576d3db27e5ace963cd3c..0ad360c7d89c37bdccc8997d24460b49f51f00e3 100644 (file)
@@ -1,9 +1,9 @@
 //! Defines the set of legal keys that can be used in queries.
 
 use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, LOCAL_CRATE};
-use rustc_hir::HirId;
 use rustc_middle::infer::canonical::Canonical;
 use rustc_middle::mir;
+use rustc_middle::traits;
 use rustc_middle::ty::fast_reject::SimplifiedType;
 use rustc_middle::ty::subst::{GenericArg, SubstsRef};
 use rustc_middle::ty::{self, Ty, TyCtxt};
@@ -397,7 +397,7 @@ fn default_span(&self, _tcx: TyCtxt<'_>) -> Span {
     }
 }
 
-impl<'tcx> Key for (ty::Predicate<'tcx>, HirId) {
+impl<'tcx> Key for (ty::Predicate<'tcx>, traits::WellFormedLoc) {
     #[inline(always)]
     fn query_crate_is_local(&self) -> bool {
         true
index b444f66258a8e8d76413f5fa4677eb86b4705866..2d7f5f9b321d1d0c99501a6b9260ac98eb47ee1b 100644 (file)
@@ -677,7 +677,6 @@ fn default() -> Options {
             optimize: OptLevel::No,
             debuginfo: DebugInfo::None,
             lint_opts: Vec::new(),
-            force_warns: Vec::new(),
             lint_cap: None,
             describe_lints: false,
             output_types: OutputTypes(BTreeMap::new()),
@@ -1102,7 +1101,7 @@ pub fn rustc_short_optgroups() -> Vec<RustcOptGroup> {
         ),
         opt::multi_s(
             "",
-            "force-warns",
+            "force-warn",
             "Specifiy lints that should warn even if \
              they are allowed somewhere else",
             "LINT",
@@ -1172,20 +1171,20 @@ pub fn get_cmd_lint_options(
     matches: &getopts::Matches,
     error_format: ErrorOutputType,
     debugging_opts: &DebuggingOptions,
-) -> (Vec<(String, lint::Level)>, bool, Option<lint::Level>, Vec<String>) {
+) -> (Vec<(String, lint::Level)>, bool, Option<lint::Level>) {
     let mut lint_opts_with_position = vec![];
     let mut describe_lints = false;
 
-    for level in [lint::Allow, lint::Warn, lint::Deny, lint::Forbid] {
-        for (passed_arg_pos, lint_name) in matches.opt_strs_pos(level.as_str()) {
-            let arg_pos = if let lint::Forbid = level {
-                // HACK: forbid is always specified last, so it can't be overridden.
-                // FIXME: remove this once <https://github.com/rust-lang/rust/issues/70819> is
-                // fixed and `forbid` works as expected.
-                usize::MAX
-            } else {
-                passed_arg_pos
-            };
+    if !debugging_opts.unstable_options && matches.opt_present("force-warn") {
+        early_error(
+            error_format,
+            "the `-Z unstable-options` flag must also be passed to enable \
+            the flag `--force-warn=lints`",
+        );
+    }
+
+    for level in [lint::Allow, lint::Warn, lint::ForceWarn, lint::Deny, lint::Forbid] {
+        for (arg_pos, lint_name) in matches.opt_strs_pos(level.as_str()) {
             if lint_name == "help" {
                 describe_lints = true;
             } else {
@@ -1206,18 +1205,7 @@ pub fn get_cmd_lint_options(
             .unwrap_or_else(|| early_error(error_format, &format!("unknown lint level: `{}`", cap)))
     });
 
-    if !debugging_opts.unstable_options && matches.opt_present("force-warns") {
-        early_error(
-            error_format,
-            "the `-Z unstable-options` flag must also be passed to enable \
-            the flag `--force-warns=lints`",
-        );
-    }
-
-    let force_warns =
-        matches.opt_strs("force-warns").into_iter().map(|name| name.replace('-', "_")).collect();
-
-    (lint_opts, describe_lints, lint_cap, force_warns)
+    (lint_opts, describe_lints, lint_cap)
 }
 
 /// Parses the `--color` flag.
@@ -1955,7 +1943,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
         .unwrap_or_else(|e| early_error(error_format, &e[..]));
 
     let mut debugging_opts = DebuggingOptions::build(matches, error_format);
-    let (lint_opts, describe_lints, lint_cap, force_warns) =
+    let (lint_opts, describe_lints, lint_cap) =
         get_cmd_lint_options(matches, error_format, &debugging_opts);
 
     check_debug_option_stability(&debugging_opts, error_format, json_rendered);
@@ -2129,7 +2117,6 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
         optimize: opt_level,
         debuginfo,
         lint_opts,
-        force_warns,
         lint_cap,
         describe_lints,
         output_types,
index 8e2e33f2d51508d51aed04554ad64d8837009754..d7b9c91173754da37c8ff18aa48c73de0b1ff708 100644 (file)
@@ -135,7 +135,6 @@ pub struct Options {
         debuginfo: DebugInfo [TRACKED],
         lint_opts: Vec<(String, lint::Level)> [TRACKED_NO_CRATE_HASH],
         lint_cap: Option<lint::Level> [TRACKED_NO_CRATE_HASH],
-        force_warns: Vec<String> [TRACKED_NO_CRATE_HASH],
         describe_lints: bool [UNTRACKED],
         output_types: OutputTypes [TRACKED],
         search_paths: Vec<SearchPath> [UNTRACKED],
index cb3a08439d1290bc4940186d3759415a594e5dd3..e44a2e96598ce40401b244eeae6bfdaf1fd50854 100644 (file)
@@ -1071,7 +1071,7 @@ pub enum AstPass {
 }
 
 impl AstPass {
-    fn descr(self) -> &'static str {
+    pub fn descr(self) -> &'static str {
         match self {
             AstPass::StdImports => "standard library imports",
             AstPass::TestHarness => "test harness",
@@ -1108,7 +1108,7 @@ pub enum ForLoopLoc {
 
 impl DesugaringKind {
     /// The description wording should combine well with "desugaring of {}".
-    fn descr(self) -> &'static str {
+    pub fn descr(self) -> &'static str {
         match self {
             DesugaringKind::CondTemporary => "`if` or `while` condition",
             DesugaringKind::Async => "`async` block or function",
index cc98cd72566281674fdc2ba32b363571c51c7f5e..39013a317fd9c494af6c94439bea66dbc5df7ad4 100644 (file)
@@ -402,9 +402,7 @@ fn constrain_opaque_type<FRR: FreeRegionRelations<'tcx>>(
             }
             // These opaque type inherit all lifetime parameters from their
             // parent, so we have to check them all.
-            hir::OpaqueTyOrigin::Binding
-            | hir::OpaqueTyOrigin::TyAlias
-            | hir::OpaqueTyOrigin::Misc => 0,
+            hir::OpaqueTyOrigin::TyAlias => 0,
         };
 
         let span = tcx.def_span(def_id);
@@ -996,7 +994,7 @@ fn instantiate_opaque_types_in_map<T: TypeFoldable<'tcx>>(&mut self, value: T) -
                                     may_define_opaque_type(tcx, self.parent_def_id, opaque_hir_id),
                                     origin,
                                 ),
-                                _ => (def_scope_default(), hir::OpaqueTyOrigin::Misc),
+                                _ => (def_scope_default(), hir::OpaqueTyOrigin::TyAlias),
                             };
                         if in_definition_scope {
                             let opaque_type_key =
index 5c4aef529e5ac775c24d6f042080e68a93c6d263..13a6733fb478abebca8f623ed2c8ae4eb930fd69 100644 (file)
@@ -242,11 +242,11 @@ fn report_selection_error(
             SelectionError::Unimplemented => {
                 // If this obligation was generated as a result of well-formed checking, see if we
                 // can get a better error message by performing HIR-based well formed checking.
-                if let ObligationCauseCode::WellFormed(Some(wf_hir_id)) =
+                if let ObligationCauseCode::WellFormed(Some(wf_loc)) =
                     root_obligation.cause.code.peel_derives()
                 {
                     if let Some(cause) =
-                        self.tcx.diagnostic_hir_wf_check((obligation.predicate, *wf_hir_id))
+                        self.tcx.diagnostic_hir_wf_check((obligation.predicate, wf_loc.clone()))
                     {
                         obligation.cause = cause;
                         span = obligation.cause.span;
index adeb1d58d1ece72ff2dbdd6382978973be8dd1d5..1c6a83b578305cce376304f40c9a956deedbbb37 100644 (file)
@@ -1903,7 +1903,8 @@ fn note_obligation_cause_code<T>(
             | ObligationCauseCode::UnifyReceiver(..)
             | ObligationCauseCode::OpaqueType
             | ObligationCauseCode::MiscObligation
-            | ObligationCauseCode::WellFormed(..) => {}
+            | ObligationCauseCode::WellFormed(..)
+            | ObligationCauseCode::MatchImpl(..) => {}
             ObligationCauseCode::SliceOrArrayElem => {
                 err.note("slice and array elements must have `Sized` type");
             }
@@ -1928,12 +1929,12 @@ fn note_obligation_cause_code<T>(
             ObligationCauseCode::ItemObligation(item_def_id) => {
                 let item_name = tcx.def_path_str(item_def_id);
                 let msg = format!("required by `{}`", item_name);
-                if let Some(sp) = tcx.hir().span_if_local(item_def_id) {
-                    let sp = tcx.sess.source_map().guess_head_span(sp);
-                    err.span_label(sp, &msg);
-                } else {
-                    err.note(&msg);
-                }
+                let sp = tcx
+                    .hir()
+                    .span_if_local(item_def_id)
+                    .unwrap_or_else(|| tcx.def_span(item_def_id));
+                let sp = tcx.sess.source_map().guess_head_span(sp);
+                err.span_note(sp, &msg);
             }
             ObligationCauseCode::BindingObligation(item_def_id, span) => {
                 let item_name = tcx.def_path_str(item_def_id);
@@ -1952,7 +1953,10 @@ fn note_obligation_cause_code<T>(
                 if span != DUMMY_SP {
                     err.span_label(span, &msg);
                 } else {
-                    err.note(&msg);
+                    err.span_note(
+                        tcx.def_span(item_def_id),
+                        &format!("required by a bound in `{}`", item_name),
+                    );
                 }
             }
             ObligationCauseCode::ObjectCastObligation(object_ty) => {
@@ -1979,9 +1983,8 @@ fn note_obligation_cause_code<T>(
 
                 if self.tcx.sess.is_nightly_build() && is_const_fn {
                     err.help(
-                        "create an inline `const` block, see RFC \
-                        #2920 <https://github.com/rust-lang/rfcs/pull/2920> \
-                        for more information",
+                        "create an inline `const` block, see RFC #2920 \
+                         <https://github.com/rust-lang/rfcs/pull/2920> for more information",
                     );
                 }
             }
@@ -2168,8 +2171,14 @@ fn note_obligation_cause_code<T>(
                 self.tcx.for_each_relevant_impl(
                     parent_def_id,
                     parent_trait_ref.self_ty().skip_binder(),
-                    |impl_def_id| {
-                        candidates.push(impl_def_id);
+                    |impl_def_id| match self.tcx.hir().get_if_local(impl_def_id) {
+                        Some(Node::Item(hir::Item {
+                            kind: hir::ItemKind::Impl(hir::Impl { .. }),
+                            ..
+                        })) => {
+                            candidates.push(impl_def_id);
+                        }
+                        _ => {}
                     },
                 );
                 match &candidates[..] {
index dfe2909498d1862ecaceed5bb5636f4cae822667..9ec1dd5c2ee3b302efd8c64613476c1c8b4a5820 100644 (file)
@@ -365,6 +365,7 @@ fn progress_changed_obligations(
                     let project_obligation = obligation.with(binder.rebind(data));
 
                     self.process_projection_obligation(
+                        obligation,
                         project_obligation,
                         &mut pending_obligation.stalled_on,
                     )
@@ -419,6 +420,7 @@ fn progress_changed_obligations(
                     let project_obligation = obligation.with(Binder::dummy(*data));
 
                     self.process_projection_obligation(
+                        obligation,
                         project_obligation,
                         &mut pending_obligation.stalled_on,
                     )
@@ -666,10 +668,22 @@ fn process_trait_obligation(
 
     fn process_projection_obligation(
         &mut self,
+        obligation: &PredicateObligation<'tcx>,
         project_obligation: PolyProjectionObligation<'tcx>,
         stalled_on: &mut Vec<TyOrConstInferVar<'tcx>>,
     ) -> ProcessResult<PendingPredicateObligation<'tcx>, FulfillmentErrorCode<'tcx>> {
         let tcx = self.selcx.tcx();
+
+        if obligation.predicate.is_global() {
+            // no type variables present, can use evaluation for better caching.
+            // FIXME: consider caching errors too.
+            if self.selcx.infcx().predicate_must_hold_considering_regions(obligation) {
+                return ProcessResult::Changed(vec![]);
+            } else {
+                tracing::debug!("Does NOT hold: {:?}", obligation);
+            }
+        }
+
         match project::poly_project_and_unify_type(self.selcx, &project_obligation) {
             Ok(Ok(Some(os))) => ProcessResult::Changed(mk_pending(os)),
             Ok(Ok(None)) => {
index b83a4cd1e5775c5af9a5195de09c37819c1669e2..2dc48e47efccdf6a9e150b8e3e88b844a82422ea 100644 (file)
@@ -64,8 +64,10 @@ fn evaluate_obligation(
         obligation: &PredicateObligation<'tcx>,
     ) -> Result<EvaluationResult, OverflowError> {
         let mut _orig_values = OriginalQueryValues::default();
-        let c_pred = self
-            .canonicalize_query(obligation.param_env.and(obligation.predicate), &mut _orig_values);
+        let c_pred = self.canonicalize_query_keep_static(
+            obligation.param_env.and(obligation.predicate),
+            &mut _orig_values,
+        );
         // Run canonical query. If overflow occurs, rerun from scratch but this time
         // in standard trait query mode so that overflow is handled appropriately
         // within `SelectionContext`.
index d65a378b1edec193ecd750f7c23ad6b76ffe6dab..3f6efa03b3a28b27694bab4c2743c857285f10ac 100644 (file)
@@ -180,7 +180,7 @@ fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
                 // so we cannot canonicalize it.
                 let c_data = self
                     .infcx
-                    .canonicalize_hr_query_hack(self.param_env.and(data), &mut orig_values);
+                    .canonicalize_query_keep_static(self.param_env.and(data), &mut orig_values);
                 debug!("QueryNormalizer: c_data = {:#?}", c_data);
                 debug!("QueryNormalizer: orig_values = {:#?}", orig_values);
                 match tcx.normalize_projection_ty(c_data) {
@@ -249,7 +249,7 @@ fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
                 // so we cannot canonicalize it.
                 let c_data = self
                     .infcx
-                    .canonicalize_hr_query_hack(self.param_env.and(data), &mut orig_values);
+                    .canonicalize_query_keep_static(self.param_env.and(data), &mut orig_values);
                 debug!("QueryNormalizer: c_data = {:#?}", c_data);
                 debug!("QueryNormalizer: orig_values = {:#?}", orig_values);
                 let normalized_ty = match tcx.normalize_projection_ty(c_data) {
index 130ffa1a33aebc7eb8aa89d2c2f37b13f4842371..fbff86618ade3172f15be2bbeb0259685ea84a8c 100644 (file)
@@ -77,12 +77,13 @@ fn fully_perform_into(
         }
 
         // FIXME(#33684) -- We need to use
-        // `canonicalize_hr_query_hack` here because of things
+        // `canonicalize_query_keep_static` here because of things
         // like the subtype query, which go awry around
         // `'static` otherwise.
         let mut canonical_var_values = OriginalQueryValues::default();
         let old_param_env = query_key.param_env;
-        let canonical_self = infcx.canonicalize_hr_query_hack(query_key, &mut canonical_var_values);
+        let canonical_self =
+            infcx.canonicalize_query_keep_static(query_key, &mut canonical_var_values);
         let canonical_result = Self::perform_query(infcx.tcx, canonical_self)?;
 
         let InferOk { value, obligations } = infcx
index 564c63ef30cb66411aa63f0afbb0259e696d4d81..95611ebc8188cfe54fc6a0258bd29d8e00ee7a35 100644 (file)
@@ -216,7 +216,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
     pub fn new(infcx: &'cx InferCtxt<'cx, 'tcx>) -> SelectionContext<'cx, 'tcx> {
         SelectionContext {
             infcx,
-            freshener: infcx.freshener(),
+            freshener: infcx.freshener_keep_static(),
             intercrate: false,
             intercrate_ambiguity_causes: None,
             allow_negative_impls: false,
@@ -227,7 +227,7 @@ pub fn new(infcx: &'cx InferCtxt<'cx, 'tcx>) -> SelectionContext<'cx, 'tcx> {
     pub fn intercrate(infcx: &'cx InferCtxt<'cx, 'tcx>) -> SelectionContext<'cx, 'tcx> {
         SelectionContext {
             infcx,
-            freshener: infcx.freshener(),
+            freshener: infcx.freshener_keep_static(),
             intercrate: true,
             intercrate_ambiguity_causes: None,
             allow_negative_impls: false,
@@ -242,7 +242,7 @@ pub fn with_negative(
         debug!(?allow_negative_impls, "with_negative");
         SelectionContext {
             infcx,
-            freshener: infcx.freshener(),
+            freshener: infcx.freshener_keep_static(),
             intercrate: false,
             intercrate_ambiguity_causes: None,
             allow_negative_impls,
@@ -257,7 +257,7 @@ pub fn with_query_mode(
         debug!(?query_mode, "with_query_mode");
         SelectionContext {
             infcx,
-            freshener: infcx.freshener(),
+            freshener: infcx.freshener_keep_static(),
             intercrate: false,
             intercrate_ambiguity_causes: None,
             allow_negative_impls: false,
@@ -1903,9 +1903,15 @@ fn match_impl(
 
         debug!(?impl_trait_ref, ?placeholder_obligation_trait_ref);
 
+        let cause = ObligationCause::new(
+            obligation.cause.span,
+            obligation.cause.body_id,
+            ObligationCauseCode::MatchImpl(Lrc::new(obligation.cause.code.clone()), impl_def_id),
+        );
+
         let InferOk { obligations, .. } = self
             .infcx
-            .at(&obligation.cause, obligation.param_env)
+            .at(&cause, obligation.param_env)
             .eq(placeholder_obligation_trait_ref, impl_trait_ref)
             .map_err(|e| debug!("match_impl: failed eq_trait_refs due to `{}`", e))?;
         nested_obligations.extend(obligations);
index 3d20a8d5cf336be07e4efca3b70ace80d7806f52..a6323a65aadbce9c4a451c13fc5049422a34eb9c 100644 (file)
@@ -19,7 +19,6 @@ pub enum NonStructuralMatchTy<'tcx> {
     Opaque,
     Generator,
     Projection,
-    Closure,
 }
 
 /// This method traverses the structure of `ty`, trying to find an
@@ -155,9 +154,6 @@ fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
             ty::Generator(..) | ty::GeneratorWitness(..) => {
                 return ControlFlow::Break(NonStructuralMatchTy::Generator);
             }
-            ty::Closure(..) => {
-                return ControlFlow::Break(NonStructuralMatchTy::Closure);
-            }
             ty::RawPtr(..) => {
                 // structural-match ignores substructure of
                 // `*const _`/`*mut _`, so skip `super_visit_with`.
@@ -198,7 +194,7 @@ fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
                 // First check all contained types and then tell the caller to continue searching.
                 return ty.super_visit_with(self);
             }
-            ty::Infer(_) | ty::Placeholder(_) | ty::Bound(..) => {
+            ty::Closure(..) | ty::Infer(_) | ty::Placeholder(_) | ty::Bound(..) => {
                 bug!("unexpected type during structural-match checking: {:?}", ty);
             }
             ty::Error(_) => {
index 2e42d65cce29bef8d80f1c8663f8fd4cedda107a..f55e274ef8ea3f4a039c5e27696a0777e76aa794 100644 (file)
@@ -838,6 +838,7 @@ pub fn is_unsized(&self, ast_bounds: &[hir::GenericBound<'_>], span: Span) -> bo
                              this does nothing because the given bound is not \
                              a default; only `?Sized` is supported",
                         );
+                        return false;
                     }
                 }
             }
index 496721e6f7634f54706a468573979a7a3840ea2f..b5db3331d044781bca42a36d6956cd2d9ed2d39e 100644 (file)
@@ -221,9 +221,7 @@ pub(super) fn check_fn<'a, 'tcx>(
         fcx.resume_yield_tys = Some((resume_ty, yield_ty));
     }
 
-    let outer_def_id = tcx.closure_base_def_id(hir.local_def_id(fn_id).to_def_id()).expect_local();
-    let outer_hir_id = hir.local_def_id_to_hir_id(outer_def_id);
-    GatherLocalsVisitor::new(&fcx, outer_hir_id).visit_body(body);
+    GatherLocalsVisitor::new(&fcx).visit_body(body);
 
     // C-variadic fns also have a `VaList` input that's not listed in `fn_sig`
     // (as it's created inside the body itself, not passed in from outside).
@@ -665,13 +663,9 @@ pub(super) fn check_opaque_for_cycles<'tcx>(
     span: Span,
     origin: &hir::OpaqueTyOrigin,
 ) -> Result<(), ErrorReported> {
-    if let Err(partially_expanded_type) = tcx.try_expand_impl_trait_type(def_id.to_def_id(), substs)
-    {
+    if tcx.try_expand_impl_trait_type(def_id.to_def_id(), substs).is_err() {
         match origin {
             hir::OpaqueTyOrigin::AsyncFn => async_opaque_type_cycle_error(tcx, span),
-            hir::OpaqueTyOrigin::Binding => {
-                binding_opaque_type_cycle_error(tcx, def_id, span, partially_expanded_type)
-            }
             _ => opaque_type_cycle_error(tcx, def_id, span),
         }
         Err(ErrorReported)
@@ -704,8 +698,7 @@ fn check_opaque_meets_bounds<'tcx>(
         // Checked when type checking the function containing them.
         hir::OpaqueTyOrigin::FnReturn | hir::OpaqueTyOrigin::AsyncFn => return,
         // Can have different predicates to their defining use
-        hir::OpaqueTyOrigin::Binding | hir::OpaqueTyOrigin::Misc | hir::OpaqueTyOrigin::TyAlias => {
-        }
+        hir::OpaqueTyOrigin::TyAlias => {}
     }
 
     let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
index 4ed07ba358de3b3794d76c9f0f7538b37545dcc8..865e4ccc0b63f506b7c7e237e76fc764ffa20b1c 100644 (file)
@@ -40,6 +40,7 @@
 use rustc_trait_selection::traits::error_reporting::InferCtxtExt as _;
 use rustc_trait_selection::traits::{
     self, ObligationCause, ObligationCauseCode, StatementAsExpression, TraitEngine, TraitEngineExt,
+    WellFormedLoc,
 };
 
 use std::collections::hash_map::Entry;
@@ -419,13 +420,13 @@ pub(in super::super) fn normalize_associated_types_in_wf<T>(
         &self,
         span: Span,
         value: T,
-        hir_id: hir::HirId,
+        loc: WellFormedLoc,
     ) -> T
     where
         T: TypeFoldable<'tcx>,
     {
         self.inh.normalize_associated_types_in_with_cause(
-            ObligationCause::new(span, self.body_id, ObligationCauseCode::WellFormed(Some(hir_id))),
+            ObligationCause::new(span, self.body_id, ObligationCauseCode::WellFormed(Some(loc))),
             self.param_env,
             value,
         )
index 4da4835f7cfbb065ab561ea414ed95b77e2a5399..13686cfec809a8635e683129330341d1a222a62e 100644 (file)
@@ -15,7 +15,6 @@
 use rustc_infer::infer;
 use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
 use rustc_infer::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind};
-use rustc_middle::hir::map::blocks::FnLikeNode;
 use rustc_middle::ty::fold::TypeFoldable;
 use rustc_middle::ty::subst::GenericArgKind;
 use rustc_middle::ty::{self, Const, Ty, TyCtxt};
@@ -175,13 +174,7 @@ fn item_def_id(&self) -> Option<DefId> {
     }
 
     fn default_constness_for_trait_bounds(&self) -> hir::Constness {
-        // FIXME: refactor this into a method
-        let node = self.tcx.hir().get(self.body_id);
-        if let Some(fn_like) = FnLikeNode::from_node(node) {
-            fn_like.constness()
-        } else {
-            hir::Constness::NotConst
-        }
+        self.tcx.hir().get(self.body_id).constness()
     }
 
     fn get_type_parameter_bounds(
index 2683e886eeb0f1ebb6664bed44fca837cdb3d6d7..4ebfd7fd21200aad744e75699ed87959f78439e7 100644 (file)
@@ -4,12 +4,11 @@
 use rustc_hir::PatKind;
 use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
 use rustc_middle::ty::Ty;
-use rustc_span::{sym, Span};
+use rustc_span::Span;
 use rustc_trait_selection::traits;
 
 pub(super) struct GatherLocalsVisitor<'a, 'tcx> {
     fcx: &'a FnCtxt<'a, 'tcx>,
-    parent_id: hir::HirId,
     // parameters are special cases of patterns, but we want to handle them as
     // *distinct* cases. so track when we are hitting a pattern *within* an fn
     // parameter.
@@ -17,8 +16,8 @@ pub(super) struct GatherLocalsVisitor<'a, 'tcx> {
 }
 
 impl<'a, 'tcx> GatherLocalsVisitor<'a, 'tcx> {
-    pub(super) fn new(fcx: &'a FnCtxt<'a, 'tcx>, parent_id: hir::HirId) -> Self {
-        Self { fcx, parent_id, outermost_fn_param_pat: None }
+    pub(super) fn new(fcx: &'a FnCtxt<'a, 'tcx>) -> Self {
+        Self { fcx, outermost_fn_param_pat: None }
     }
 
     fn assign(&mut self, span: Span, nid: hir::HirId, ty_opt: Option<LocalTy<'tcx>>) -> Ty<'tcx> {
@@ -57,26 +56,15 @@ fn visit_local(&mut self, local: &'tcx hir::Local<'tcx>) {
             Some(ref ty) => {
                 let o_ty = self.fcx.to_ty(&ty);
 
-                let revealed_ty = self.fcx.instantiate_opaque_types_from_value(
-                    self.parent_id,
-                    o_ty,
-                    ty.span,
-                    Some(sym::impl_trait_in_bindings),
-                );
-
-                let c_ty =
-                    self.fcx.inh.infcx.canonicalize_user_type_annotation(UserType::Ty(revealed_ty));
-                debug!(
-                    "visit_local: ty.hir_id={:?} o_ty={:?} revealed_ty={:?} c_ty={:?}",
-                    ty.hir_id, o_ty, revealed_ty, c_ty
-                );
+                let c_ty = self.fcx.inh.infcx.canonicalize_user_type_annotation(UserType::Ty(o_ty));
+                debug!("visit_local: ty.hir_id={:?} o_ty={:?} c_ty={:?}", ty.hir_id, o_ty, c_ty);
                 self.fcx
                     .typeck_results
                     .borrow_mut()
                     .user_provided_types_mut()
                     .insert(ty.hir_id, c_ty);
 
-                Some(LocalTy { decl_ty: o_ty, revealed_ty })
+                Some(LocalTy { decl_ty: o_ty, revealed_ty: o_ty })
             }
             None => None,
         };
index 7f4754448ba84e040eba621bb4d6741639d1d88e..77586ce48529c897c94ad1733cc6a8927d69dceb 100644 (file)
@@ -933,6 +933,12 @@ trait bound{s}",
                     item_name
                 );
                 err.span_label(item_name.span, &format!("private {}", kind));
+                let sp = self
+                    .tcx
+                    .hir()
+                    .span_if_local(def_id)
+                    .unwrap_or_else(|| self.tcx.def_span(def_id));
+                err.span_label(sp, &format!("private {} defined here", kind));
                 self.suggest_valid_traits(&mut err, out_of_scope_traits);
                 err.emit();
             }
index 34d0908bcc74ea2df8f1aad5e16ef24a5f869537..d30b057e26fe369b403258cd34610e97fc4d8680 100644 (file)
 use rustc_session::config;
 use rustc_session::parse::feature_err;
 use rustc_session::Session;
+use rustc_span::source_map::DUMMY_SP;
 use rustc_span::symbol::{kw, Ident};
 use rustc_span::{self, BytePos, MultiSpan, Span};
-use rustc_span::{source_map::DUMMY_SP, sym};
 use rustc_target::abi::VariantIdx;
 use rustc_target::spec::abi::Abi;
 use rustc_trait_selection::traits;
@@ -441,19 +441,12 @@ fn typeck_with_fallback<'tcx>(
             let expected_type = fcx.normalize_associated_types_in(body.value.span, expected_type);
             fcx.require_type_is_sized(expected_type, body.value.span, traits::ConstSized);
 
-            let revealed_ty = fcx.instantiate_opaque_types_from_value(
-                id,
-                expected_type,
-                body.value.span,
-                Some(sym::impl_trait_in_bindings),
-            );
-
             // Gather locals in statics (because of block expressions).
-            GatherLocalsVisitor::new(&fcx, id).visit_body(body);
+            GatherLocalsVisitor::new(&fcx).visit_body(body);
 
-            fcx.check_expr_coercable_to_type(&body.value, revealed_ty, None);
+            fcx.check_expr_coercable_to_type(&body.value, expected_type, None);
 
-            fcx.write_ty(id, revealed_ty);
+            fcx.write_ty(id, expected_type);
 
             fcx
         };
@@ -573,66 +566,6 @@ fn get_owner_return_paths(
         })
 }
 
-/// Emit an error for recursive opaque types in a `let` binding.
-fn binding_opaque_type_cycle_error(
-    tcx: TyCtxt<'tcx>,
-    def_id: LocalDefId,
-    span: Span,
-    partially_expanded_type: Ty<'tcx>,
-) {
-    let mut err = struct_span_err!(tcx.sess, span, E0720, "cannot resolve opaque type");
-    err.span_label(span, "cannot resolve opaque type");
-    // Find the owner that declared this `impl Trait` type.
-    let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
-    let mut prev_hir_id = hir_id;
-    let mut hir_id = tcx.hir().get_parent_node(hir_id);
-    while let Some(node) = tcx.hir().find(hir_id) {
-        match node {
-            hir::Node::Local(hir::Local {
-                pat,
-                init: None,
-                ty: Some(ty),
-                source: hir::LocalSource::Normal,
-                ..
-            }) => {
-                err.span_label(pat.span, "this binding might not have a concrete type");
-                err.span_suggestion_verbose(
-                    ty.span.shrink_to_hi(),
-                    "set the binding to a value for a concrete type to be resolved",
-                    " = /* value */".to_string(),
-                    Applicability::HasPlaceholders,
-                );
-            }
-            hir::Node::Local(hir::Local {
-                init: Some(expr),
-                source: hir::LocalSource::Normal,
-                ..
-            }) => {
-                let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
-                let typeck_results =
-                    tcx.typeck(tcx.hir().local_def_id(tcx.hir().get_parent_item(hir_id)));
-                if let Some(ty) = typeck_results.node_type_opt(expr.hir_id) {
-                    err.span_label(
-                        expr.span,
-                        &format!(
-                            "this is of type `{}`, which doesn't constrain \
-                             `{}` enough to arrive to a concrete type",
-                            ty, partially_expanded_type
-                        ),
-                    );
-                }
-            }
-            _ => {}
-        }
-        if prev_hir_id == hir_id {
-            break;
-        }
-        prev_hir_id = hir_id;
-        hir_id = tcx.hir().get_parent_node(hir_id);
-    }
-    err.emit();
-}
-
 // Forbid defining intrinsics in Rust code,
 // as they must always be defined by the compiler.
 fn fn_maybe_err(tcx: TyCtxt<'_>, sp: Span, abi: Abi) {
index b24d63917c1cf48a72eb97e8aced98dd93d95d00..98980c65bc815dcd1831cb61139bc518d82b3ac8 100644 (file)
@@ -22,8 +22,9 @@
 use rustc_span::Span;
 use rustc_trait_selection::opaque_types::may_define_opaque_type;
 use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt;
-use rustc_trait_selection::traits::{self, ObligationCause, ObligationCauseCode};
+use rustc_trait_selection::traits::{self, ObligationCause, ObligationCauseCode, WellFormedLoc};
 
+use std::convert::TryInto;
 use std::iter;
 use std::ops::ControlFlow;
 
@@ -386,7 +387,7 @@ fn check_associated_item(
     span: Span,
     sig_if_method: Option<&hir::FnSig<'_>>,
 ) {
-    let code = ObligationCauseCode::WellFormed(Some(item_id));
+    let code = ObligationCauseCode::WellFormed(Some(WellFormedLoc::Ty(item_id.expect_owner())));
     for_id(tcx, item_id, span).with_fcx(|fcx| {
         let item = fcx.tcx.associated_item(fcx.tcx.hir().local_def_id(item_id));
 
@@ -400,7 +401,11 @@ fn check_associated_item(
         match item.kind {
             ty::AssocKind::Const => {
                 let ty = fcx.tcx.type_of(item.def_id);
-                let ty = fcx.normalize_associated_types_in_wf(span, ty, item_id);
+                let ty = fcx.normalize_associated_types_in_wf(
+                    span,
+                    ty,
+                    WellFormedLoc::Ty(item_id.expect_owner()),
+                );
                 fcx.register_wf_obligation(ty.into(), span, code.clone());
             }
             ty::AssocKind::Fn => {
@@ -422,7 +427,11 @@ fn check_associated_item(
                 }
                 if item.defaultness.has_value() {
                     let ty = fcx.tcx.type_of(item.def_id);
-                    let ty = fcx.normalize_associated_types_in_wf(span, ty, item_id);
+                    let ty = fcx.normalize_associated_types_in_wf(
+                        span,
+                        ty,
+                        WellFormedLoc::Ty(item_id.expect_owner()),
+                    );
                     fcx.register_wf_obligation(ty.into(), span, code.clone());
                 }
             }
@@ -621,7 +630,11 @@ fn check_item_type(tcx: TyCtxt<'_>, item_id: hir::HirId, ty_span: Span, allow_fo
 
     for_id(tcx, item_id, ty_span).with_fcx(|fcx| {
         let ty = tcx.type_of(tcx.hir().local_def_id(item_id));
-        let item_ty = fcx.normalize_associated_types_in_wf(ty_span, ty, item_id);
+        let item_ty = fcx.normalize_associated_types_in_wf(
+            ty_span,
+            ty,
+            WellFormedLoc::Ty(item_id.expect_owner()),
+        );
 
         let mut forbid_unsized = true;
         if allow_foreign_ty {
@@ -634,7 +647,7 @@ fn check_item_type(tcx: TyCtxt<'_>, item_id: hir::HirId, ty_span: Span, allow_fo
         fcx.register_wf_obligation(
             item_ty.into(),
             ty_span,
-            ObligationCauseCode::WellFormed(Some(item_id)),
+            ObligationCauseCode::WellFormed(Some(WellFormedLoc::Ty(item_id.expect_owner()))),
         );
         if forbid_unsized {
             fcx.register_bound(
@@ -684,7 +697,9 @@ fn check_impl<'tcx>(
                 fcx.register_wf_obligation(
                     self_ty.into(),
                     ast_self_ty.span,
-                    ObligationCauseCode::WellFormed(Some(item.hir_id())),
+                    ObligationCauseCode::WellFormed(Some(WellFormedLoc::Ty(
+                        item.hir_id().expect_owner(),
+                    ))),
                 );
             }
         }
@@ -901,11 +916,48 @@ fn check_fn_or_method<'fcx, 'tcx>(
     implied_bounds: &mut Vec<Ty<'tcx>>,
 ) {
     let sig = fcx.tcx.liberate_late_bound_regions(def_id, sig);
-    let sig = fcx.normalize_associated_types_in(span, sig);
 
-    for (&input_ty, ty) in iter::zip(sig.inputs(), hir_decl.inputs) {
-        fcx.register_wf_obligation(input_ty.into(), ty.span, ObligationCauseCode::WellFormed(None));
+    // Normalize the input and output types one at a time, using a different
+    // `WellFormedLoc` for each. We cannot call `normalize_associated_types`
+    // on the entire `FnSig`, since this would use the same `WellFormedLoc`
+    // for each type, preventing the HIR wf check from generating
+    // a nice error message.
+    let ty::FnSig { mut inputs_and_output, c_variadic, unsafety, abi } = sig;
+    inputs_and_output =
+        fcx.tcx.mk_type_list(inputs_and_output.iter().enumerate().map(|(i, ty)| {
+            fcx.normalize_associated_types_in_wf(
+                span,
+                ty,
+                WellFormedLoc::Param {
+                    function: def_id.expect_local(),
+                    // Note that the `param_idx` of the output type is
+                    // one greater than the index of the last input type.
+                    param_idx: i.try_into().unwrap(),
+                },
+            )
+        }));
+    // Manually call `normalize_assocaited_types_in` on the other types
+    // in `FnSig`. This ensures that if the types of these fields
+    // ever change to include projections, we will start normalizing
+    // them automatically.
+    let sig = ty::FnSig {
+        inputs_and_output,
+        c_variadic: fcx.normalize_associated_types_in(span, c_variadic),
+        unsafety: fcx.normalize_associated_types_in(span, unsafety),
+        abi: fcx.normalize_associated_types_in(span, abi),
+    };
+
+    for (i, (&input_ty, ty)) in iter::zip(sig.inputs(), hir_decl.inputs).enumerate() {
+        fcx.register_wf_obligation(
+            input_ty.into(),
+            ty.span,
+            ObligationCauseCode::WellFormed(Some(WellFormedLoc::Param {
+                function: def_id.expect_local(),
+                param_idx: i.try_into().unwrap(),
+            })),
+        );
     }
+
     implied_bounds.extend(sig.inputs());
 
     fcx.register_wf_obligation(
index 0aa059b7de80fde78df7e570f621be4bbb307541..935bcc9f32e2bb16a5b1be3587f398ef79433064 100644 (file)
@@ -521,8 +521,7 @@ fn visit_opaque_types(&mut self, span: Span) {
             let mut skip_add = false;
 
             if let ty::Opaque(definition_ty_def_id, _substs) = *definition_ty.kind() {
-                if let hir::OpaqueTyOrigin::Misc | hir::OpaqueTyOrigin::TyAlias = opaque_defn.origin
-                {
+                if opaque_defn.origin == hir::OpaqueTyOrigin::TyAlias {
                     if opaque_type_key.def_id == definition_ty_def_id {
                         debug!(
                             "skipping adding concrete definition for opaque type {:?} {:?}",
index 506ca98b96026180e84e5be71fb5b07161e4fbb3..1a4c2eb5155849168bcb719b3763737abc840ea3 100644 (file)
@@ -35,7 +35,6 @@
 use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
 use rustc_hir::weak_lang_items;
 use rustc_hir::{GenericParamKind, HirId, Node};
-use rustc_middle::hir::map::blocks::FnLikeNode;
 use rustc_middle::hir::map::Map;
 use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs};
 use rustc_middle::mir::mono::Linkage;
@@ -358,11 +357,7 @@ fn item_def_id(&self) -> Option<DefId> {
     }
 
     fn default_constness_for_trait_bounds(&self) -> hir::Constness {
-        if let Some(fn_like) = FnLikeNode::from_node(self.node()) {
-            fn_like.constness()
-        } else {
-            hir::Constness::NotConst
-        }
+        self.node().constness()
     }
 
     fn get_type_parameter_bounds(
index 7b0002914eca80d20d0df9cf6e94bfa4dbfe933f..15469cb0066c50ec60112fb493d8e0a32653d224 100644 (file)
@@ -356,9 +356,6 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
                     let substs = InternalSubsts::identity_for_item(tcx, def_id.to_def_id());
                     tcx.mk_adt(def, substs)
                 }
-                ItemKind::OpaqueTy(OpaqueTy { origin: hir::OpaqueTyOrigin::Binding, .. }) => {
-                    let_position_impl_trait_type(tcx, def_id)
-                }
                 ItemKind::OpaqueTy(OpaqueTy { impl_trait_fn: None, .. }) => {
                     find_opaque_ty_constraints(tcx, def_id)
                 }
@@ -696,60 +693,6 @@ fn visit_trait_item(&mut self, it: &'tcx TraitItem<'tcx>) {
     }
 }
 
-/// Retrieve the inferred concrete type for let position impl trait.
-///
-/// This is different to other kinds of impl trait because:
-///
-/// 1. We know which function contains the defining use (the function that
-///    contains the let statement)
-/// 2. We do not currently allow (free) lifetimes in the return type. `let`
-///    statements in some statically unreachable code are removed from the MIR
-///    by the time we borrow check, and it's not clear how we should handle
-///    those.
-fn let_position_impl_trait_type(tcx: TyCtxt<'_>, opaque_ty_id: LocalDefId) -> Ty<'_> {
-    let scope = tcx.hir().get_defining_scope(tcx.hir().local_def_id_to_hir_id(opaque_ty_id));
-    let scope_def_id = tcx.hir().local_def_id(scope);
-
-    let opaque_ty_def_id = opaque_ty_id.to_def_id();
-
-    let owner_typeck_results = tcx.typeck(scope_def_id);
-    let concrete_ty = owner_typeck_results
-        .concrete_opaque_types
-        .get_by(|(key, _)| key.def_id == opaque_ty_def_id)
-        .map(|concrete_ty| *concrete_ty)
-        .unwrap_or_else(|| {
-            tcx.sess.delay_span_bug(
-                DUMMY_SP,
-                &format!(
-                    "owner {:?} has no opaque type for {:?} in its typeck results",
-                    scope_def_id, opaque_ty_id
-                ),
-            );
-            if let Some(ErrorReported) = owner_typeck_results.tainted_by_errors {
-                // Some error in the owner fn prevented us from populating the
-                // `concrete_opaque_types` table.
-                tcx.ty_error()
-            } else {
-                // We failed to resolve the opaque type or it resolves to
-                // itself. Return the non-revealed type, which should result in
-                // E0720.
-                tcx.mk_opaque(
-                    opaque_ty_def_id,
-                    InternalSubsts::identity_for_item(tcx, opaque_ty_def_id),
-                )
-            }
-        });
-    debug!("concrete_ty = {:?}", concrete_ty);
-    if concrete_ty.has_erased_regions() {
-        // FIXME(impl_trait_in_bindings) Handle this case.
-        tcx.sess.span_fatal(
-            tcx.hir().span(tcx.hir().local_def_id_to_hir_id(opaque_ty_id)),
-            "lifetimes in impl Trait types in bindings are not currently supported",
-        );
-    }
-    concrete_ty
-}
-
 fn infer_placeholder_type<'a>(
     tcx: TyCtxt<'a>,
     def_id: LocalDefId,
index a8ec7b79e571f284141e7343e525a86ea6faba56..c1af10f5ce45125c5bab44482b19f9aa68ee111b 100644 (file)
@@ -3,10 +3,10 @@
 use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
 use rustc_hir::HirId;
 use rustc_infer::infer::TyCtxtInferExt;
-use rustc_infer::traits::ObligationCause;
 use rustc_infer::traits::TraitEngine;
+use rustc_infer::traits::{ObligationCause, WellFormedLoc};
 use rustc_middle::ty::query::Providers;
-use rustc_middle::ty::{self, ToPredicate, TyCtxt};
+use rustc_middle::ty::{self, Region, ToPredicate, TyCtxt, TypeFoldable, TypeFolder};
 use rustc_trait_selection::traits;
 
 pub fn provide(providers: &mut Providers) {
@@ -17,21 +17,20 @@ pub fn provide(providers: &mut Providers) {
 // need access to `ItemCtxt`
 fn diagnostic_hir_wf_check<'tcx>(
     tcx: TyCtxt<'tcx>,
-    (predicate, hir_id): (ty::Predicate<'tcx>, HirId),
+    (predicate, loc): (ty::Predicate<'tcx>, WellFormedLoc),
 ) -> Option<ObligationCause<'tcx>> {
     let hir = tcx.hir();
-    // HIR wfcheck should only ever happen as part of improving an existing error
-    tcx.sess.delay_span_bug(hir.span(hir_id), "Performed HIR wfcheck without an existing error!");
 
-    // Currently, we only handle WF checking for items (e.g. associated items).
-    // It would be nice to extend this to handle wf checks inside functions.
-    let def_id = match tcx.hir().opt_local_def_id(hir_id) {
-        Some(def_id) => def_id,
-        None => return None,
+    let def_id = match loc {
+        WellFormedLoc::Ty(def_id) => def_id,
+        WellFormedLoc::Param { function, param_idx: _ } => function,
     };
+    let hir_id = HirId::make_owner(def_id);
+
+    // HIR wfcheck should only ever happen as part of improving an existing error
+    tcx.sess
+        .delay_span_bug(tcx.def_span(def_id), "Performed HIR wfcheck without an existing error!");
 
-    // FIXME - figure out how we want to handle wf-checking for
-    // things inside a function body.
     let icx = ItemCtxt::new(tcx, def_id.to_def_id());
 
     // To perform HIR-based WF checking, we iterate over all HIR types
@@ -72,7 +71,8 @@ fn nested_visit_map(&mut self) -> NestedVisitorMap<Self::Map> {
         fn visit_ty(&mut self, ty: &'tcx hir::Ty<'tcx>) {
             self.tcx.infer_ctxt().enter(|infcx| {
                 let mut fulfill = traits::FulfillmentContext::new();
-                let tcx_ty = self.icx.to_ty(ty);
+                let tcx_ty =
+                    self.icx.to_ty(ty).fold_with(&mut EraseAllBoundRegions { tcx: self.tcx });
                 let cause = traits::ObligationCause::new(
                     ty.span,
                     self.hir_id,
@@ -119,19 +119,66 @@ fn visit_ty(&mut self, ty: &'tcx hir::Ty<'tcx>) {
         depth: 0,
     };
 
-    let ty = match tcx.hir().get(hir_id) {
-        hir::Node::ImplItem(item) => match item.kind {
-            hir::ImplItemKind::TyAlias(ty) => Some(ty),
-            _ => None,
-        },
-        hir::Node::TraitItem(item) => match item.kind {
-            hir::TraitItemKind::Type(_, ty) => ty,
-            _ => None,
+    // Get the starting `hir::Ty` using our `WellFormedLoc`.
+    // We will walk 'into' this type to try to find
+    // a more precise span for our predicate.
+    let ty = match loc {
+        WellFormedLoc::Ty(_) => match hir.get(hir_id) {
+            hir::Node::ImplItem(item) => match item.kind {
+                hir::ImplItemKind::TyAlias(ty) => Some(ty),
+                ref item => bug!("Unexpected ImplItem {:?}", item),
+            },
+            hir::Node::TraitItem(item) => match item.kind {
+                hir::TraitItemKind::Type(_, ty) => ty,
+                ref item => bug!("Unexpected TraitItem {:?}", item),
+            },
+            hir::Node::Item(item) => match item.kind {
+                hir::ItemKind::Static(ty, _, _) | hir::ItemKind::Const(ty, _) => Some(ty),
+                hir::ItemKind::Impl(ref impl_) => {
+                    assert!(impl_.of_trait.is_none(), "Unexpected trait impl: {:?}", impl_);
+                    Some(impl_.self_ty)
+                }
+                ref item => bug!("Unexpected item {:?}", item),
+            },
+            ref node => bug!("Unexpected node {:?}", node),
         },
-        _ => None,
+        WellFormedLoc::Param { function: _, param_idx } => {
+            let fn_decl = hir.fn_decl_by_hir_id(hir_id).unwrap();
+            // Get return type
+            if param_idx as usize == fn_decl.inputs.len() {
+                match fn_decl.output {
+                    hir::FnRetTy::Return(ty) => Some(ty),
+                    // The unit type `()` is always well-formed
+                    hir::FnRetTy::DefaultReturn(_span) => None,
+                }
+            } else {
+                Some(&fn_decl.inputs[param_idx as usize])
+            }
+        }
     };
     if let Some(ty) = ty {
         visitor.visit_ty(ty);
     }
     visitor.cause
 }
+
+struct EraseAllBoundRegions<'tcx> {
+    tcx: TyCtxt<'tcx>,
+}
+
+// Higher ranked regions are complicated.
+// To make matters worse, the HIR WF check can instantiate them
+// outside of a `Binder`, due to the way we (ab)use
+// `ItemCtxt::to_ty`. To make things simpler, we just erase all
+// of them, regardless of depth. At worse, this will give
+// us an inaccurate span for an error message, but cannot
+// lead to unsoundess (we call `delay_span_bug` at the start
+// of `diagnostic_hir_wf_check`).
+impl<'tcx> TypeFolder<'tcx> for EraseAllBoundRegions<'tcx> {
+    fn tcx<'a>(&'a self) -> TyCtxt<'tcx> {
+        self.tcx
+    }
+    fn fold_region(&mut self, r: Region<'tcx>) -> Region<'tcx> {
+        if let ty::ReLateBound(..) = r { &ty::ReErased } else { r }
+    }
+}
index 6dcc110f1539c104ba3a560599bb47ffe7e096ca..0a098c8e2d98633d158e50f175ee7fda400e6cc7 100644 (file)
 ///
 /// # Example
 ///
-/// ```no_run
-/// use std::alloc::{GlobalAlloc, Layout, alloc};
+/// ```
+/// use std::alloc::{GlobalAlloc, Layout};
+/// use std::cell::UnsafeCell;
 /// use std::ptr::null_mut;
+/// use std::sync::atomic::{
+///     AtomicUsize,
+///     Ordering::{Acquire, SeqCst},
+/// };
 ///
-/// struct MyAllocator;
-///
-/// unsafe impl GlobalAlloc for MyAllocator {
-///     unsafe fn alloc(&self, _layout: Layout) -> *mut u8 { null_mut() }
-///     unsafe fn dealloc(&self, _ptr: *mut u8, _layout: Layout) {}
+/// const ARENA_SIZE: usize = 128 * 1024;
+/// const MAX_SUPPORTED_ALIGN: usize = 4096;
+/// #[repr(C, align(4096))] // 4096 == MAX_SUPPORTED_ALIGN
+/// struct SimpleAllocator {
+///     arena: UnsafeCell<[u8; ARENA_SIZE]>,
+///     remaining: AtomicUsize, // we allocate from the top, counting down
 /// }
 ///
 /// #[global_allocator]
-/// static A: MyAllocator = MyAllocator;
+/// static ALLOCATOR: SimpleAllocator = SimpleAllocator {
+///     arena: UnsafeCell::new([0x55; ARENA_SIZE]),
+///     remaining: AtomicUsize::new(ARENA_SIZE),
+/// };
 ///
-/// fn main() {
-///     unsafe {
-///         assert!(alloc(Layout::new::<u32>()).is_null())
+/// unsafe impl Sync for SimpleAllocator {}
+///
+/// unsafe impl GlobalAlloc for SimpleAllocator {
+///     unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
+///         let size = layout.size();
+///         let align = layout.align();
+///
+///         // `Layout` contract forbids making a `Layout` with align=0, or align not power of 2.
+///         // So we can safely use a mask to ensure alignment without worrying about UB.
+///         let align_mask_to_round_down = !(align - 1);
+///
+///         if align > MAX_SUPPORTED_ALIGN {
+///             return null_mut();
+///         }
+///
+///         let mut allocated = 0;
+///         if self
+///             .remaining
+///             .fetch_update(SeqCst, SeqCst, |mut remaining| {
+///                 if size > remaining {
+///                     return None;
+///                 }
+///                 remaining -= size;
+///                 remaining &= align_mask_to_round_down;
+///                 allocated = remaining;
+///                 Some(remaining)
+///             })
+///             .is_err()
+///         {
+///             return null_mut();
+///         };
+///         (self.arena.get() as *mut u8).add(allocated)
 ///     }
+///     unsafe fn dealloc(&self, _ptr: *mut u8, _layout: Layout) {}
+/// }
+///
+/// fn main() {
+///     let _s = format!("allocating a string!");
+///     let currently = ALLOCATOR.remaining.load(Acquire);
+///     println!("allocated so far: {}", ARENA_SIZE - currently);
 /// }
 /// ```
 ///
index 3315d346596114e5e691987adee90c30c59bcc00..48880a4d91a57c9e42ca28c9d9898ba5b3062d30 100644 (file)
@@ -1,5 +1,5 @@
 use crate::fmt;
-use crate::iter::{DoubleEndedIterator, Fuse, FusedIterator, Iterator, Map};
+use crate::iter::{DoubleEndedIterator, Fuse, FusedIterator, Iterator, Map, TrustedLen};
 use crate::ops::Try;
 
 /// An iterator that maps each element to an iterator, and yields the elements
@@ -114,6 +114,30 @@ impl<I, U, F> FusedIterator for FlatMap<I, U, F>
 {
 }
 
+#[unstable(feature = "trusted_len", issue = "37572")]
+unsafe impl<T, I, F, const N: usize> TrustedLen for FlatMap<I, [T; N], F>
+where
+    I: TrustedLen,
+    F: FnMut(I::Item) -> [T; N],
+{
+}
+
+#[unstable(feature = "trusted_len", issue = "37572")]
+unsafe impl<'a, T, I, F, const N: usize> TrustedLen for FlatMap<I, &'a [T; N], F>
+where
+    I: TrustedLen,
+    F: FnMut(I::Item) -> &'a [T; N],
+{
+}
+
+#[unstable(feature = "trusted_len", issue = "37572")]
+unsafe impl<'a, T, I, F, const N: usize> TrustedLen for FlatMap<I, &'a mut [T; N], F>
+where
+    I: TrustedLen,
+    F: FnMut(I::Item) -> &'a mut [T; N],
+{
+}
+
 /// An iterator that flattens one level of nesting in an iterator of things
 /// that can be turned into iterators.
 ///
@@ -230,6 +254,14 @@ impl<I, U> FusedIterator for Flatten<I>
 {
 }
 
+#[unstable(feature = "trusted_len", issue = "37572")]
+unsafe impl<I> TrustedLen for Flatten<I>
+where
+    I: TrustedLen,
+    <I as Iterator>::Item: TrustedConstSize,
+{
+}
+
 /// Real logic of both `Flatten` and `FlatMap` which simply delegate to
 /// this type.
 #[derive(Clone, Debug)]
@@ -282,6 +314,17 @@ fn size_hint(&self) -> (usize, Option<usize>) {
         let (flo, fhi) = self.frontiter.as_ref().map_or((0, Some(0)), U::size_hint);
         let (blo, bhi) = self.backiter.as_ref().map_or((0, Some(0)), U::size_hint);
         let lo = flo.saturating_add(blo);
+
+        if let Some(fixed_size) = <<I as Iterator>::Item as ConstSizeIntoIterator>::size() {
+            let (lower, upper) = self.iter.size_hint();
+
+            let lower = lower.saturating_mul(fixed_size).saturating_add(lo);
+            let upper =
+                try { fhi?.checked_add(bhi?)?.checked_add(fixed_size.checked_mul(upper?)?)? };
+
+            return (lower, upper);
+        }
+
         match (self.iter.size_hint(), fhi, bhi) {
             ((0, Some(0)), Some(a), Some(b)) => (lo, a.checked_add(b)),
             _ => (lo, None),
@@ -444,3 +487,52 @@ fn flatten<T: IntoIterator, Acc>(
         init
     }
 }
+
+trait ConstSizeIntoIterator: IntoIterator {
+    // FIXME(#31844): convert to an associated const once specialization supports that
+    fn size() -> Option<usize>;
+}
+
+impl<T> ConstSizeIntoIterator for T
+where
+    T: IntoIterator,
+{
+    #[inline]
+    default fn size() -> Option<usize> {
+        None
+    }
+}
+
+impl<T, const N: usize> ConstSizeIntoIterator for [T; N] {
+    #[inline]
+    fn size() -> Option<usize> {
+        Some(N)
+    }
+}
+
+impl<T, const N: usize> ConstSizeIntoIterator for &[T; N] {
+    #[inline]
+    fn size() -> Option<usize> {
+        Some(N)
+    }
+}
+
+impl<T, const N: usize> ConstSizeIntoIterator for &mut [T; N] {
+    #[inline]
+    fn size() -> Option<usize> {
+        Some(N)
+    }
+}
+
+#[doc(hidden)]
+#[unstable(feature = "std_internals", issue = "none")]
+// FIXME(#20400): Instead of this helper trait there should be multiple impl TrustedLen for Flatten<>
+//   blocks with different bounds on Iterator::Item but the compiler erroneously considers them overlapping
+pub unsafe trait TrustedConstSize: IntoIterator {}
+
+#[unstable(feature = "std_internals", issue = "none")]
+unsafe impl<T, const N: usize> TrustedConstSize for [T; N] {}
+#[unstable(feature = "std_internals", issue = "none")]
+unsafe impl<T, const N: usize> TrustedConstSize for &'_ [T; N] {}
+#[unstable(feature = "std_internals", issue = "none")]
+unsafe impl<T, const N: usize> TrustedConstSize for &'_ mut [T; N] {}
index 4bbae6947bf66ed9b90a0f42b0cf541fff1158b4..aaac39c297933f240d386f9e5123e9bfcd9da815 100644 (file)
@@ -1,4 +1,5 @@
 use super::*;
+use core::array;
 use core::iter::*;
 
 #[test]
@@ -109,3 +110,42 @@ fn test_double_ended_flatten() {
     assert_eq!(it.next(), None);
     assert_eq!(it.next_back(), None);
 }
+
+#[test]
+fn test_trusted_len_flatten() {
+    fn assert_trusted_len<T: TrustedLen>(_: &T) {}
+    let mut iter = array::IntoIter::new([[0; 3]; 4]).flatten();
+    assert_trusted_len(&iter);
+
+    assert_eq!(iter.size_hint(), (12, Some(12)));
+    iter.next();
+    assert_eq!(iter.size_hint(), (11, Some(11)));
+    iter.next_back();
+    assert_eq!(iter.size_hint(), (10, Some(10)));
+
+    let iter = array::IntoIter::new([[(); usize::MAX]; 1]).flatten();
+    assert_eq!(iter.size_hint(), (usize::MAX, Some(usize::MAX)));
+
+    let iter = array::IntoIter::new([[(); usize::MAX]; 2]).flatten();
+    assert_eq!(iter.size_hint(), (usize::MAX, None));
+
+    let mut a = [(); 10];
+    let mut b = [(); 10];
+
+    let iter = array::IntoIter::new([&mut a, &mut b]).flatten();
+    assert_trusted_len(&iter);
+    assert_eq!(iter.size_hint(), (20, Some(20)));
+    core::mem::drop(iter);
+
+    let iter = array::IntoIter::new([&a, &b]).flatten();
+    assert_trusted_len(&iter);
+    assert_eq!(iter.size_hint(), (20, Some(20)));
+
+    let iter = [(), (), ()].iter().flat_map(|_| [(); 1000]);
+    assert_trusted_len(&iter);
+    assert_eq!(iter.size_hint(), (3000, Some(3000)));
+
+    let iter = [(), ()].iter().flat_map(|_| &a);
+    assert_trusted_len(&iter);
+    assert_eq!(iter.size_hint(), (20, Some(20)));
+}
index 206687e38fb9cfc402121d3c24c000124092102e..65ad7d88e22d5dbe5066c232e5043c5d65828cae 100644 (file)
@@ -7,7 +7,7 @@
 
 use crate::cell::{Cell, RefCell};
 use crate::fmt;
-use crate::io::{self, BufReader, Initializer, IoSlice, IoSliceMut, LineWriter};
+use crate::io::{self, BufReader, Initializer, IoSlice, IoSliceMut, LineWriter, Lines, Split};
 use crate::lazy::SyncOnceCell;
 use crate::pin::Pin;
 use crate::sync::atomic::{AtomicBool, Ordering};
@@ -446,6 +446,49 @@ fn lock_any<'a>(&self) -> StdinLock<'a> {
     pub fn into_locked(self) -> StdinLock<'static> {
         self.lock_any()
     }
+
+    /// Consumes this handle and returns an iterator over input lines.
+    ///
+    /// For detailed semantics of this method, see the documentation on
+    /// [`BufRead::lines`].
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// #![feature(stdin_forwarders)]
+    /// use std::io;
+    ///
+    /// let lines = io::stdin().lines();
+    /// for line in lines {
+    ///     println!("got a line: {}", line.unwrap());
+    /// }
+    /// ```
+    #[unstable(feature = "stdin_forwarders", issue = "87096")]
+    pub fn lines(self) -> Lines<StdinLock<'static>> {
+        self.into_locked().lines()
+    }
+
+    /// Consumes this handle and returns an iterator over input bytes,
+    /// split at the specified byte value.
+    ///
+    /// For detailed semantics of this method, see the documentation on
+    /// [`BufRead::split`].
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// #![feature(stdin_forwarders)]
+    /// use std::io;
+    ///
+    /// let splits = io::stdin().split(b'-');
+    /// for split in splits {
+    ///     println!("got a chunk: {}", String::from_utf8_lossy(&split.unwrap()));
+    /// }
+    /// ```
+    #[unstable(feature = "stdin_forwarders", issue = "87096")]
+    pub fn split(self, byte: u8) -> Split<StdinLock<'static>> {
+        self.into_locked().split(byte)
+    }
 }
 
 #[stable(feature = "std_debug", since = "1.16.0")]
index ad93fa610c4819fe7d7c7c4acf32a67d4ab978a7..0bd1ea645779f6d524e1cb9e27156bcfe3f82b38 100644 (file)
@@ -77,10 +77,18 @@ mod imp {
     use crate::ptr;
     use crate::sync::atomic::{AtomicIsize, AtomicPtr, Ordering};
 
+    // The system-provided argc and argv, which we store in static memory
+    // here so that we can defer the work of parsing them until its actually
+    // needed.
+    //
+    // Note that we never mutate argv/argc, the argv array, or the argv
+    // strings, which allows the code in this file to be very simple.
     static ARGC: AtomicIsize = AtomicIsize::new(0);
     static ARGV: AtomicPtr<*const u8> = AtomicPtr::new(ptr::null_mut());
 
     unsafe fn really_init(argc: isize, argv: *const *const u8) {
+        // These don't need to be ordered with each other or other stores,
+        // because they only hold the unmodified system-provide argv/argc.
         ARGC.store(argc, Ordering::Relaxed);
         ARGV.store(argv as *mut _, Ordering::Relaxed);
     }
@@ -122,8 +130,14 @@ pub fn args() -> Args {
 
     fn clone() -> Vec<OsString> {
         unsafe {
-            // Load ARGC and ARGV without a lock. If the store to either ARGV or
-            // ARGC isn't visible yet, we'll return an empty argument list.
+            // Load ARGC and ARGV, which hold the unmodified system-provided
+            // argc/argv, so we can read the pointed-to memory without atomics
+            // or synchronization.
+            //
+            // If either ARGC or ARGV is still zero or null, then either there
+            // really are no arguments, or someone is asking for `args()`
+            // before initialization has completed, and we return an empty
+            // list.
             let argv = ARGV.load(Ordering::Relaxed);
             let argc = if argv.is_null() { 0 } else { ARGC.load(Ordering::Relaxed) };
             (0..argc)
diff --git a/library/term/Cargo.toml b/library/term/Cargo.toml
deleted file mode 100644 (file)
index ddf85b5..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-[package]
-authors = ["The Rust Project Developers"]
-name = "term"
-version = "0.0.0"
-edition = "2018"
-
-[dependencies]
-core = { path = "../core" }
-std = { path = "../std" }
diff --git a/library/term/src/lib.rs b/library/term/src/lib.rs
deleted file mode 100644 (file)
index 943b276..0000000
+++ /dev/null
@@ -1,194 +0,0 @@
-//! Terminal formatting library.
-//!
-//! This crate provides the `Terminal` trait, which abstracts over an [ANSI
-//! Terminal][ansi] to provide color printing, among other things. There are two
-//! implementations, the `TerminfoTerminal`, which uses control characters from
-//! a [terminfo][ti] database, and `WinConsole`, which uses the [Win32 Console
-//! API][win].
-//!
-//! # Examples
-//!
-//! ```no_run
-//! # #![feature(rustc_private)]
-//! extern crate term;
-//! use std::io::prelude::*;
-//!
-//! fn main() {
-//!     let mut t = term::stdout().unwrap();
-//!
-//!     t.fg(term::color::GREEN).unwrap();
-//!     write!(t, "hello, ").unwrap();
-//!
-//!     t.fg(term::color::RED).unwrap();
-//!     writeln!(t, "world!").unwrap();
-//!
-//!     assert!(t.reset().unwrap());
-//! }
-//! ```
-//!
-//! [ansi]: https://en.wikipedia.org/wiki/ANSI_escape_code
-//! [win]: https://docs.microsoft.com/en-us/windows/console/character-mode-applications
-//! [ti]: https://en.wikipedia.org/wiki/Terminfo
-
-#![doc(html_playground_url = "https://play.rust-lang.org/", test(attr(deny(warnings))))]
-#![deny(missing_docs)]
-#![cfg_attr(windows, feature(libc))]
-
-use std::io::prelude::*;
-use std::io::{self, Stderr, Stdout};
-
-pub use terminfo::TerminfoTerminal;
-#[cfg(windows)]
-pub use win::WinConsole;
-
-pub mod terminfo;
-
-#[cfg(windows)]
-mod win;
-
-/// Alias for stdout terminals.
-pub type StdoutTerminal = dyn Terminal<Output = Stdout> + Send;
-/// Alias for stderr terminals.
-pub type StderrTerminal = dyn Terminal<Output = Stderr> + Send;
-
-#[cfg(not(windows))]
-/// Returns a Terminal wrapping stdout, or None if a terminal couldn't be
-/// opened.
-pub fn stdout() -> Option<Box<StdoutTerminal>> {
-    TerminfoTerminal::new(io::stdout()).map(|t| Box::new(t) as Box<StdoutTerminal>)
-}
-
-#[cfg(windows)]
-/// Returns a Terminal wrapping stdout, or None if a terminal couldn't be
-/// opened.
-pub fn stdout() -> Option<Box<StdoutTerminal>> {
-    TerminfoTerminal::new(io::stdout())
-        .map(|t| Box::new(t) as Box<StdoutTerminal>)
-        .or_else(|| WinConsole::new(io::stdout()).ok().map(|t| Box::new(t) as Box<StdoutTerminal>))
-}
-
-#[cfg(not(windows))]
-/// Returns a Terminal wrapping stderr, or None if a terminal couldn't be
-/// opened.
-pub fn stderr() -> Option<Box<StderrTerminal>> {
-    TerminfoTerminal::new(io::stderr()).map(|t| Box::new(t) as Box<StderrTerminal>)
-}
-
-#[cfg(windows)]
-/// Returns a Terminal wrapping stderr, or None if a terminal couldn't be
-/// opened.
-pub fn stderr() -> Option<Box<StderrTerminal>> {
-    TerminfoTerminal::new(io::stderr())
-        .map(|t| Box::new(t) as Box<StderrTerminal>)
-        .or_else(|| WinConsole::new(io::stderr()).ok().map(|t| Box::new(t) as Box<StderrTerminal>))
-}
-
-/// Terminal color definitions
-#[allow(missing_docs)]
-pub mod color {
-    /// Number for a terminal color
-    pub type Color = u32;
-
-    pub const BLACK: Color = 0;
-    pub const RED: Color = 1;
-    pub const GREEN: Color = 2;
-    pub const YELLOW: Color = 3;
-    pub const BLUE: Color = 4;
-    pub const MAGENTA: Color = 5;
-    pub const CYAN: Color = 6;
-    pub const WHITE: Color = 7;
-
-    pub const BRIGHT_BLACK: Color = 8;
-    pub const BRIGHT_RED: Color = 9;
-    pub const BRIGHT_GREEN: Color = 10;
-    pub const BRIGHT_YELLOW: Color = 11;
-    pub const BRIGHT_BLUE: Color = 12;
-    pub const BRIGHT_MAGENTA: Color = 13;
-    pub const BRIGHT_CYAN: Color = 14;
-    pub const BRIGHT_WHITE: Color = 15;
-}
-
-/// Terminal attributes for use with term.attr().
-///
-/// Most attributes can only be turned on and must be turned off with term.reset().
-/// The ones that can be turned off explicitly take a boolean value.
-/// Color is also represented as an attribute for convenience.
-#[derive(Debug, PartialEq, Eq, Copy, Clone)]
-pub enum Attr {
-    /// Bold (or possibly bright) mode
-    Bold,
-    /// Dim mode, also called faint or half-bright. Often not supported
-    Dim,
-    /// Italics mode. Often not supported
-    Italic(bool),
-    /// Underline mode
-    Underline(bool),
-    /// Blink mode
-    Blink,
-    /// Standout mode. Often implemented as Reverse, sometimes coupled with Bold
-    Standout(bool),
-    /// Reverse mode, inverts the foreground and background colors
-    Reverse,
-    /// Secure mode, also called invis mode. Hides the printed text
-    Secure,
-    /// Convenience attribute to set the foreground color
-    ForegroundColor(color::Color),
-    /// Convenience attribute to set the background color
-    BackgroundColor(color::Color),
-}
-
-/// A terminal with similar capabilities to an ANSI Terminal
-/// (foreground/background colors etc).
-pub trait Terminal: Write {
-    /// The terminal's output writer type.
-    type Output: Write;
-
-    /// Sets the foreground color to the given color.
-    ///
-    /// If the color is a bright color, but the terminal only supports 8 colors,
-    /// the corresponding normal color will be used instead.
-    ///
-    /// Returns `Ok(true)` if the color was set, `Ok(false)` otherwise, and `Err(e)`
-    /// if there was an I/O error.
-    fn fg(&mut self, color: color::Color) -> io::Result<bool>;
-
-    /// Sets the background color to the given color.
-    ///
-    /// If the color is a bright color, but the terminal only supports 8 colors,
-    /// the corresponding normal color will be used instead.
-    ///
-    /// Returns `Ok(true)` if the color was set, `Ok(false)` otherwise, and `Err(e)`
-    /// if there was an I/O error.
-    fn bg(&mut self, color: color::Color) -> io::Result<bool>;
-
-    /// Sets the given terminal attribute, if supported. Returns `Ok(true)`
-    /// if the attribute was supported, `Ok(false)` otherwise, and `Err(e)` if
-    /// there was an I/O error.
-    fn attr(&mut self, attr: Attr) -> io::Result<bool>;
-
-    /// Returns `true` if the given terminal attribute is supported.
-    fn supports_attr(&self, attr: Attr) -> bool;
-
-    /// Resets all terminal attributes and colors to their defaults.
-    ///
-    /// Returns `Ok(true)` if the terminal was reset, `Ok(false)` otherwise, and `Err(e)` if there
-    /// was an I/O error.
-    ///
-    /// *Note: This does not flush.*
-    ///
-    /// That means the reset command may get buffered so, if you aren't planning on doing anything
-    /// else that might flush stdout's buffer (e.g., writing a line of text), you should flush after
-    /// calling reset.
-    fn reset(&mut self) -> io::Result<bool>;
-
-    /// Gets an immutable reference to the stream inside
-    fn get_ref(&self) -> &Self::Output;
-
-    /// Gets a mutable reference to the stream inside
-    fn get_mut(&mut self) -> &mut Self::Output;
-
-    /// Returns the contained stream, destroying the `Terminal`
-    fn into_inner(self) -> Self::Output
-    where
-        Self: Sized;
-}
diff --git a/library/term/src/terminfo/mod.rs b/library/term/src/terminfo/mod.rs
deleted file mode 100644 (file)
index fec59aa..0000000
+++ /dev/null
@@ -1,245 +0,0 @@
-//! Terminfo database interface.
-
-use std::collections::HashMap;
-use std::env;
-use std::error;
-use std::fmt;
-use std::fs::File;
-use std::io::{self, prelude::*, BufReader};
-use std::path::Path;
-
-use crate::color;
-use crate::Attr;
-use crate::Terminal;
-
-use parm::{expand, Param, Variables};
-use parser::compiled::{msys_terminfo, parse};
-use searcher::get_dbpath_for_term;
-
-/// A parsed terminfo database entry.
-#[derive(Debug)]
-pub struct TermInfo {
-    /// Names for the terminal
-    pub names: Vec<String>,
-    /// Map of capability name to boolean value
-    pub bools: HashMap<String, bool>,
-    /// Map of capability name to numeric value
-    pub numbers: HashMap<String, u32>,
-    /// Map of capability name to raw (unexpanded) string
-    pub strings: HashMap<String, Vec<u8>>,
-}
-
-/// A terminfo creation error.
-#[derive(Debug)]
-pub enum Error {
-    /// TermUnset Indicates that the environment doesn't include enough information to find
-    /// the terminfo entry.
-    TermUnset,
-    /// MalformedTerminfo indicates that parsing the terminfo entry failed.
-    MalformedTerminfo(String),
-    /// io::Error forwards any io::Errors encountered when finding or reading the terminfo entry.
-    IoError(io::Error),
-}
-
-impl error::Error for Error {
-    fn source(&self) -> Option<&(dyn error::Error + 'static)> {
-        use Error::*;
-        match self {
-            IoError(e) => Some(e),
-            _ => None,
-        }
-    }
-}
-
-impl fmt::Display for Error {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        use Error::*;
-        match *self {
-            TermUnset => Ok(()),
-            MalformedTerminfo(ref e) => e.fmt(f),
-            IoError(ref e) => e.fmt(f),
-        }
-    }
-}
-
-impl TermInfo {
-    /// Creates a TermInfo based on current environment.
-    pub fn from_env() -> Result<TermInfo, Error> {
-        let term = match env::var("TERM") {
-            Ok(name) => TermInfo::from_name(&name),
-            Err(..) => return Err(Error::TermUnset),
-        };
-
-        if term.is_err() && env::var("MSYSCON").map_or(false, |s| "mintty.exe" == s) {
-            // msys terminal
-            Ok(msys_terminfo())
-        } else {
-            term
-        }
-    }
-
-    /// Creates a TermInfo for the named terminal.
-    pub fn from_name(name: &str) -> Result<TermInfo, Error> {
-        get_dbpath_for_term(name)
-            .ok_or_else(|| {
-                Error::IoError(io::Error::new(io::ErrorKind::NotFound, "terminfo file not found"))
-            })
-            .and_then(|p| TermInfo::from_path(&(*p)))
-    }
-
-    /// Parse the given TermInfo.
-    pub fn from_path<P: AsRef<Path>>(path: P) -> Result<TermInfo, Error> {
-        Self::_from_path(path.as_ref())
-    }
-    // Keep the metadata small
-    fn _from_path(path: &Path) -> Result<TermInfo, Error> {
-        let file = File::open(path).map_err(Error::IoError)?;
-        let mut reader = BufReader::new(file);
-        parse(&mut reader, false).map_err(Error::MalformedTerminfo)
-    }
-}
-
-pub mod searcher;
-
-/// TermInfo format parsing.
-pub mod parser {
-    //! ncurses-compatible compiled terminfo format parsing (term(5))
-    pub mod compiled;
-}
-pub mod parm;
-
-fn cap_for_attr(attr: Attr) -> &'static str {
-    match attr {
-        Attr::Bold => "bold",
-        Attr::Dim => "dim",
-        Attr::Italic(true) => "sitm",
-        Attr::Italic(false) => "ritm",
-        Attr::Underline(true) => "smul",
-        Attr::Underline(false) => "rmul",
-        Attr::Blink => "blink",
-        Attr::Standout(true) => "smso",
-        Attr::Standout(false) => "rmso",
-        Attr::Reverse => "rev",
-        Attr::Secure => "invis",
-        Attr::ForegroundColor(_) => "setaf",
-        Attr::BackgroundColor(_) => "setab",
-    }
-}
-
-/// A Terminal that knows how many colors it supports, with a reference to its
-/// parsed Terminfo database record.
-pub struct TerminfoTerminal<T> {
-    num_colors: u32,
-    out: T,
-    ti: TermInfo,
-}
-
-impl<T: Write + Send> Terminal for TerminfoTerminal<T> {
-    type Output = T;
-    fn fg(&mut self, color: color::Color) -> io::Result<bool> {
-        let color = self.dim_if_necessary(color);
-        if self.num_colors > color {
-            return self.apply_cap("setaf", &[Param::Number(color as i32)]);
-        }
-        Ok(false)
-    }
-
-    fn bg(&mut self, color: color::Color) -> io::Result<bool> {
-        let color = self.dim_if_necessary(color);
-        if self.num_colors > color {
-            return self.apply_cap("setab", &[Param::Number(color as i32)]);
-        }
-        Ok(false)
-    }
-
-    fn attr(&mut self, attr: Attr) -> io::Result<bool> {
-        match attr {
-            Attr::ForegroundColor(c) => self.fg(c),
-            Attr::BackgroundColor(c) => self.bg(c),
-            _ => self.apply_cap(cap_for_attr(attr), &[]),
-        }
-    }
-
-    fn supports_attr(&self, attr: Attr) -> bool {
-        match attr {
-            Attr::ForegroundColor(_) | Attr::BackgroundColor(_) => self.num_colors > 0,
-            _ => {
-                let cap = cap_for_attr(attr);
-                self.ti.strings.get(cap).is_some()
-            }
-        }
-    }
-
-    fn reset(&mut self) -> io::Result<bool> {
-        // are there any terminals that have color/attrs and not sgr0?
-        // Try falling back to sgr, then op
-        let cmd = match ["sgr0", "sgr", "op"].iter().find_map(|cap| self.ti.strings.get(*cap)) {
-            Some(op) => match expand(&op, &[], &mut Variables::new()) {
-                Ok(cmd) => cmd,
-                Err(e) => return Err(io::Error::new(io::ErrorKind::InvalidData, e)),
-            },
-            None => return Ok(false),
-        };
-        self.out.write_all(&cmd).and(Ok(true))
-    }
-
-    fn get_ref(&self) -> &T {
-        &self.out
-    }
-
-    fn get_mut(&mut self) -> &mut T {
-        &mut self.out
-    }
-
-    fn into_inner(self) -> T
-    where
-        Self: Sized,
-    {
-        self.out
-    }
-}
-
-impl<T: Write + Send> TerminfoTerminal<T> {
-    /// Creates a new TerminfoTerminal with the given TermInfo and Write.
-    pub fn new_with_terminfo(out: T, terminfo: TermInfo) -> TerminfoTerminal<T> {
-        let nc = if terminfo.strings.contains_key("setaf") && terminfo.strings.contains_key("setab")
-        {
-            terminfo.numbers.get("colors").map_or(0, |&n| n)
-        } else {
-            0
-        };
-
-        TerminfoTerminal { out, ti: terminfo, num_colors: nc }
-    }
-
-    /// Creates a new TerminfoTerminal for the current environment with the given Write.
-    ///
-    /// Returns `None` when the terminfo cannot be found or parsed.
-    pub fn new(out: T) -> Option<TerminfoTerminal<T>> {
-        TermInfo::from_env().map(move |ti| TerminfoTerminal::new_with_terminfo(out, ti)).ok()
-    }
-
-    fn dim_if_necessary(&self, color: color::Color) -> color::Color {
-        if color >= self.num_colors && color >= 8 && color < 16 { color - 8 } else { color }
-    }
-
-    fn apply_cap(&mut self, cmd: &str, params: &[Param]) -> io::Result<bool> {
-        match self.ti.strings.get(cmd) {
-            Some(cmd) => match expand(&cmd, params, &mut Variables::new()) {
-                Ok(s) => self.out.write_all(&s).and(Ok(true)),
-                Err(e) => Err(io::Error::new(io::ErrorKind::InvalidData, e)),
-            },
-            None => Ok(false),
-        }
-    }
-}
-
-impl<T: Write> Write for TerminfoTerminal<T> {
-    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
-        self.out.write(buf)
-    }
-
-    fn flush(&mut self) -> io::Result<()> {
-        self.out.flush()
-    }
-}
diff --git a/library/term/src/terminfo/parm.rs b/library/term/src/terminfo/parm.rs
deleted file mode 100644 (file)
index 2e4e917..0000000
+++ /dev/null
@@ -1,559 +0,0 @@
-//! Parameterized string expansion
-
-use self::Param::*;
-use self::States::*;
-
-use std::iter::repeat;
-
-#[cfg(test)]
-mod tests;
-
-#[derive(Clone, Copy, PartialEq)]
-enum States {
-    Nothing,
-    Percent,
-    SetVar,
-    GetVar,
-    PushParam,
-    CharConstant,
-    CharClose,
-    IntConstant(i32),
-    FormatPattern(Flags, FormatState),
-    SeekIfElse(usize),
-    SeekIfElsePercent(usize),
-    SeekIfEnd(usize),
-    SeekIfEndPercent(usize),
-}
-
-#[derive(Copy, PartialEq, Clone)]
-enum FormatState {
-    Flags,
-    Width,
-    Precision,
-}
-
-/// Types of parameters a capability can use
-#[allow(missing_docs)]
-#[derive(Clone)]
-pub enum Param {
-    Words(String),
-    Number(i32),
-}
-
-/// Container for static and dynamic variable arrays
-pub struct Variables {
-    /// Static variables A-Z
-    sta_va: [Param; 26],
-    /// Dynamic variables a-z
-    dyn_va: [Param; 26],
-}
-
-impl Variables {
-    /// Returns a new zero-initialized Variables
-    pub fn new() -> Variables {
-        Variables {
-            sta_va: [
-                Number(0),
-                Number(0),
-                Number(0),
-                Number(0),
-                Number(0),
-                Number(0),
-                Number(0),
-                Number(0),
-                Number(0),
-                Number(0),
-                Number(0),
-                Number(0),
-                Number(0),
-                Number(0),
-                Number(0),
-                Number(0),
-                Number(0),
-                Number(0),
-                Number(0),
-                Number(0),
-                Number(0),
-                Number(0),
-                Number(0),
-                Number(0),
-                Number(0),
-                Number(0),
-            ],
-            dyn_va: [
-                Number(0),
-                Number(0),
-                Number(0),
-                Number(0),
-                Number(0),
-                Number(0),
-                Number(0),
-                Number(0),
-                Number(0),
-                Number(0),
-                Number(0),
-                Number(0),
-                Number(0),
-                Number(0),
-                Number(0),
-                Number(0),
-                Number(0),
-                Number(0),
-                Number(0),
-                Number(0),
-                Number(0),
-                Number(0),
-                Number(0),
-                Number(0),
-                Number(0),
-                Number(0),
-            ],
-        }
-    }
-}
-
-/// Expand a parameterized capability
-///
-/// # Arguments
-/// * `cap`    - string to expand
-/// * `params` - vector of params for %p1 etc
-/// * `vars`   - Variables struct for %Pa etc
-///
-/// To be compatible with ncurses, `vars` should be the same between calls to `expand` for
-/// multiple capabilities for the same terminal.
-pub fn expand(cap: &[u8], params: &[Param], vars: &mut Variables) -> Result<Vec<u8>, String> {
-    let mut state = Nothing;
-
-    // expanded cap will only rarely be larger than the cap itself
-    let mut output = Vec::with_capacity(cap.len());
-
-    let mut stack: Vec<Param> = Vec::new();
-
-    // Copy parameters into a local vector for mutability
-    let mut mparams = [
-        Number(0),
-        Number(0),
-        Number(0),
-        Number(0),
-        Number(0),
-        Number(0),
-        Number(0),
-        Number(0),
-        Number(0),
-    ];
-    for (dst, src) in mparams.iter_mut().zip(params.iter()) {
-        *dst = (*src).clone();
-    }
-
-    for &c in cap.iter() {
-        let cur = c as char;
-        let mut old_state = state;
-        match state {
-            Nothing => {
-                if cur == '%' {
-                    state = Percent;
-                } else {
-                    output.push(c);
-                }
-            }
-            Percent => {
-                match cur {
-                    '%' => {
-                        output.push(c);
-                        state = Nothing
-                    }
-                    'c' => {
-                        match stack.pop() {
-                            // if c is 0, use 0200 (128) for ncurses compatibility
-                            Some(Number(0)) => output.push(128u8),
-                            // Don't check bounds. ncurses just casts and truncates.
-                            Some(Number(c)) => output.push(c as u8),
-                            Some(_) => return Err("a non-char was used with %c".to_string()),
-                            None => return Err("stack is empty".to_string()),
-                        }
-                    }
-                    'p' => state = PushParam,
-                    'P' => state = SetVar,
-                    'g' => state = GetVar,
-                    '\'' => state = CharConstant,
-                    '{' => state = IntConstant(0),
-                    'l' => match stack.pop() {
-                        Some(Words(s)) => stack.push(Number(s.len() as i32)),
-                        Some(_) => return Err("a non-str was used with %l".to_string()),
-                        None => return Err("stack is empty".to_string()),
-                    },
-                    '+' | '-' | '/' | '*' | '^' | '&' | '|' | 'm' => {
-                        match (stack.pop(), stack.pop()) {
-                            (Some(Number(y)), Some(Number(x))) => stack.push(Number(match cur {
-                                '+' => x + y,
-                                '-' => x - y,
-                                '*' => x * y,
-                                '/' => x / y,
-                                '|' => x | y,
-                                '&' => x & y,
-                                '^' => x ^ y,
-                                'm' => x % y,
-                                _ => unreachable!("All cases handled"),
-                            })),
-                            (Some(_), Some(_)) => {
-                                return Err(format!("non-numbers on stack with {}", cur));
-                            }
-                            _ => return Err("stack is empty".to_string()),
-                        }
-                    }
-                    '=' | '>' | '<' | 'A' | 'O' => match (stack.pop(), stack.pop()) {
-                        (Some(Number(y)), Some(Number(x))) => stack.push(Number(
-                            if match cur {
-                                '=' => x == y,
-                                '<' => x < y,
-                                '>' => x > y,
-                                'A' => x > 0 && y > 0,
-                                'O' => x > 0 || y > 0,
-                                _ => unreachable!(),
-                            } {
-                                1
-                            } else {
-                                0
-                            },
-                        )),
-                        (Some(_), Some(_)) => {
-                            return Err(format!("non-numbers on stack with {}", cur));
-                        }
-                        _ => return Err("stack is empty".to_string()),
-                    },
-                    '!' | '~' => match stack.pop() {
-                        Some(Number(x)) => stack.push(Number(match cur {
-                            '!' if x > 0 => 0,
-                            '!' => 1,
-                            '~' => !x,
-                            _ => unreachable!(),
-                        })),
-                        Some(_) => return Err(format!("non-numbers on stack with {}", cur)),
-                        None => return Err("stack is empty".to_string()),
-                    },
-                    'i' => match (&mparams[0], &mparams[1]) {
-                        (&Number(x), &Number(y)) => {
-                            mparams[0] = Number(x + 1);
-                            mparams[1] = Number(y + 1);
-                        }
-                        _ => return Err("first two params not numbers with %i".to_string()),
-                    },
-
-                    // printf-style support for %doxXs
-                    'd' | 'o' | 'x' | 'X' | 's' => {
-                        if let Some(arg) = stack.pop() {
-                            let flags = Flags::new();
-                            let res = format(arg, FormatOp::from_char(cur), flags)?;
-                            output.extend(res.iter().cloned());
-                        } else {
-                            return Err("stack is empty".to_string());
-                        }
-                    }
-                    ':' | '#' | ' ' | '.' | '0'..='9' => {
-                        let mut flags = Flags::new();
-                        let mut fstate = FormatState::Flags;
-                        match cur {
-                            ':' => (),
-                            '#' => flags.alternate = true,
-                            ' ' => flags.space = true,
-                            '.' => fstate = FormatState::Precision,
-                            '0'..='9' => {
-                                flags.width = cur as usize - '0' as usize;
-                                fstate = FormatState::Width;
-                            }
-                            _ => unreachable!(),
-                        }
-                        state = FormatPattern(flags, fstate);
-                    }
-
-                    // conditionals
-                    '?' => (),
-                    't' => match stack.pop() {
-                        Some(Number(0)) => state = SeekIfElse(0),
-                        Some(Number(_)) => (),
-                        Some(_) => return Err("non-number on stack with conditional".to_string()),
-                        None => return Err("stack is empty".to_string()),
-                    },
-                    'e' => state = SeekIfEnd(0),
-                    ';' => (),
-                    _ => return Err(format!("unrecognized format option {}", cur)),
-                }
-            }
-            PushParam => {
-                // params are 1-indexed
-                stack.push(
-                    mparams[match cur.to_digit(10) {
-                        Some(d) => d as usize - 1,
-                        None => return Err("bad param number".to_string()),
-                    }]
-                    .clone(),
-                );
-            }
-            SetVar => {
-                if cur >= 'A' && cur <= 'Z' {
-                    if let Some(arg) = stack.pop() {
-                        let idx = (cur as u8) - b'A';
-                        vars.sta_va[idx as usize] = arg;
-                    } else {
-                        return Err("stack is empty".to_string());
-                    }
-                } else if cur >= 'a' && cur <= 'z' {
-                    if let Some(arg) = stack.pop() {
-                        let idx = (cur as u8) - b'a';
-                        vars.dyn_va[idx as usize] = arg;
-                    } else {
-                        return Err("stack is empty".to_string());
-                    }
-                } else {
-                    return Err("bad variable name in %P".to_string());
-                }
-            }
-            GetVar => {
-                if cur >= 'A' && cur <= 'Z' {
-                    let idx = (cur as u8) - b'A';
-                    stack.push(vars.sta_va[idx as usize].clone());
-                } else if cur >= 'a' && cur <= 'z' {
-                    let idx = (cur as u8) - b'a';
-                    stack.push(vars.dyn_va[idx as usize].clone());
-                } else {
-                    return Err("bad variable name in %g".to_string());
-                }
-            }
-            CharConstant => {
-                stack.push(Number(c as i32));
-                state = CharClose;
-            }
-            CharClose => {
-                if cur != '\'' {
-                    return Err("malformed character constant".to_string());
-                }
-            }
-            IntConstant(i) => {
-                if cur == '}' {
-                    stack.push(Number(i));
-                    state = Nothing;
-                } else if let Some(digit) = cur.to_digit(10) {
-                    match i.checked_mul(10).and_then(|i_ten| i_ten.checked_add(digit as i32)) {
-                        Some(i) => {
-                            state = IntConstant(i);
-                            old_state = Nothing;
-                        }
-                        None => return Err("int constant too large".to_string()),
-                    }
-                } else {
-                    return Err("bad int constant".to_string());
-                }
-            }
-            FormatPattern(ref mut flags, ref mut fstate) => {
-                old_state = Nothing;
-                match (*fstate, cur) {
-                    (_, 'd') | (_, 'o') | (_, 'x') | (_, 'X') | (_, 's') => {
-                        if let Some(arg) = stack.pop() {
-                            let res = format(arg, FormatOp::from_char(cur), *flags)?;
-                            output.extend(res.iter().cloned());
-                            // will cause state to go to Nothing
-                            old_state = FormatPattern(*flags, *fstate);
-                        } else {
-                            return Err("stack is empty".to_string());
-                        }
-                    }
-                    (FormatState::Flags, '#') => {
-                        flags.alternate = true;
-                    }
-                    (FormatState::Flags, '-') => {
-                        flags.left = true;
-                    }
-                    (FormatState::Flags, '+') => {
-                        flags.sign = true;
-                    }
-                    (FormatState::Flags, ' ') => {
-                        flags.space = true;
-                    }
-                    (FormatState::Flags, '0'..='9') => {
-                        flags.width = cur as usize - '0' as usize;
-                        *fstate = FormatState::Width;
-                    }
-                    (FormatState::Flags, '.') => {
-                        *fstate = FormatState::Precision;
-                    }
-                    (FormatState::Width, '0'..='9') => {
-                        let old = flags.width;
-                        flags.width = flags.width * 10 + (cur as usize - '0' as usize);
-                        if flags.width < old {
-                            return Err("format width overflow".to_string());
-                        }
-                    }
-                    (FormatState::Width, '.') => {
-                        *fstate = FormatState::Precision;
-                    }
-                    (FormatState::Precision, '0'..='9') => {
-                        let old = flags.precision;
-                        flags.precision = flags.precision * 10 + (cur as usize - '0' as usize);
-                        if flags.precision < old {
-                            return Err("format precision overflow".to_string());
-                        }
-                    }
-                    _ => return Err("invalid format specifier".to_string()),
-                }
-            }
-            SeekIfElse(level) => {
-                if cur == '%' {
-                    state = SeekIfElsePercent(level);
-                }
-                old_state = Nothing;
-            }
-            SeekIfElsePercent(level) => {
-                if cur == ';' {
-                    if level == 0 {
-                        state = Nothing;
-                    } else {
-                        state = SeekIfElse(level - 1);
-                    }
-                } else if cur == 'e' && level == 0 {
-                    state = Nothing;
-                } else if cur == '?' {
-                    state = SeekIfElse(level + 1);
-                } else {
-                    state = SeekIfElse(level);
-                }
-            }
-            SeekIfEnd(level) => {
-                if cur == '%' {
-                    state = SeekIfEndPercent(level);
-                }
-                old_state = Nothing;
-            }
-            SeekIfEndPercent(level) => {
-                if cur == ';' {
-                    if level == 0 {
-                        state = Nothing;
-                    } else {
-                        state = SeekIfEnd(level - 1);
-                    }
-                } else if cur == '?' {
-                    state = SeekIfEnd(level + 1);
-                } else {
-                    state = SeekIfEnd(level);
-                }
-            }
-        }
-        if state == old_state {
-            state = Nothing;
-        }
-    }
-    Ok(output)
-}
-
-#[derive(Copy, PartialEq, Clone)]
-struct Flags {
-    width: usize,
-    precision: usize,
-    alternate: bool,
-    left: bool,
-    sign: bool,
-    space: bool,
-}
-
-impl Flags {
-    fn new() -> Flags {
-        Flags { width: 0, precision: 0, alternate: false, left: false, sign: false, space: false }
-    }
-}
-
-#[derive(Copy, Clone)]
-enum FormatOp {
-    Digit,
-    Octal,
-    LowerHex,
-    UpperHex,
-    String,
-}
-
-impl FormatOp {
-    fn from_char(c: char) -> FormatOp {
-        match c {
-            'd' => FormatOp::Digit,
-            'o' => FormatOp::Octal,
-            'x' => FormatOp::LowerHex,
-            'X' => FormatOp::UpperHex,
-            's' => FormatOp::String,
-            _ => panic!("bad FormatOp char"),
-        }
-    }
-    fn to_char(self) -> char {
-        match self {
-            FormatOp::Digit => 'd',
-            FormatOp::Octal => 'o',
-            FormatOp::LowerHex => 'x',
-            FormatOp::UpperHex => 'X',
-            FormatOp::String => 's',
-        }
-    }
-}
-
-fn format(val: Param, op: FormatOp, flags: Flags) -> Result<Vec<u8>, String> {
-    let mut s = match val {
-        Number(d) => {
-            match op {
-                FormatOp::Digit => {
-                    if flags.sign {
-                        format!("{:+01$}", d, flags.precision)
-                    } else if d < 0 {
-                        // C doesn't take sign into account in precision calculation.
-                        format!("{:01$}", d, flags.precision + 1)
-                    } else if flags.space {
-                        format!(" {:01$}", d, flags.precision)
-                    } else {
-                        format!("{:01$}", d, flags.precision)
-                    }
-                }
-                FormatOp::Octal => {
-                    if flags.alternate {
-                        // Leading octal zero counts against precision.
-                        format!("0{:01$o}", d, flags.precision.saturating_sub(1))
-                    } else {
-                        format!("{:01$o}", d, flags.precision)
-                    }
-                }
-                FormatOp::LowerHex => {
-                    if flags.alternate && d != 0 {
-                        format!("0x{:01$x}", d, flags.precision)
-                    } else {
-                        format!("{:01$x}", d, flags.precision)
-                    }
-                }
-                FormatOp::UpperHex => {
-                    if flags.alternate && d != 0 {
-                        format!("0X{:01$X}", d, flags.precision)
-                    } else {
-                        format!("{:01$X}", d, flags.precision)
-                    }
-                }
-                FormatOp::String => return Err("non-number on stack with %s".to_string()),
-            }
-            .into_bytes()
-        }
-        Words(s) => match op {
-            FormatOp::String => {
-                let mut s = s.into_bytes();
-                if flags.precision > 0 && flags.precision < s.len() {
-                    s.truncate(flags.precision);
-                }
-                s
-            }
-            _ => return Err(format!("non-string on stack with %{}", op.to_char())),
-        },
-    };
-    if flags.width > s.len() {
-        let n = flags.width - s.len();
-        if flags.left {
-            s.extend(repeat(b' ').take(n));
-        } else {
-            let mut s_ = Vec::with_capacity(flags.width);
-            s_.extend(repeat(b' ').take(n));
-            s_.extend(s.into_iter());
-            s = s_;
-        }
-    }
-    Ok(s)
-}
diff --git a/library/term/src/terminfo/parm/tests.rs b/library/term/src/terminfo/parm/tests.rs
deleted file mode 100644 (file)
index 1cc0967..0000000
+++ /dev/null
@@ -1,138 +0,0 @@
-use super::*;
-
-use std::result::Result::Ok;
-
-#[test]
-fn test_basic_setabf() {
-    let s = b"\\E[48;5;%p1%dm";
-    assert_eq!(
-        expand(s, &[Number(1)], &mut Variables::new()).unwrap(),
-        "\\E[48;5;1m".bytes().collect::<Vec<_>>()
-    );
-}
-
-#[test]
-fn test_multiple_int_constants() {
-    assert_eq!(
-        expand(b"%{1}%{2}%d%d", &[], &mut Variables::new()).unwrap(),
-        "21".bytes().collect::<Vec<_>>()
-    );
-}
-
-#[test]
-fn test_op_i() {
-    let mut vars = Variables::new();
-    assert_eq!(
-        expand(b"%p1%d%p2%d%p3%d%i%p1%d%p2%d%p3%d", &[Number(1), Number(2), Number(3)], &mut vars),
-        Ok("123233".bytes().collect::<Vec<_>>())
-    );
-    assert_eq!(
-        expand(b"%p1%d%p2%d%i%p1%d%p2%d", &[], &mut vars),
-        Ok("0011".bytes().collect::<Vec<_>>())
-    );
-}
-
-#[test]
-fn test_param_stack_failure_conditions() {
-    let mut varstruct = Variables::new();
-    let vars = &mut varstruct;
-    fn get_res(
-        fmt: &str,
-        cap: &str,
-        params: &[Param],
-        vars: &mut Variables,
-    ) -> Result<Vec<u8>, String> {
-        let mut u8v: Vec<_> = fmt.bytes().collect();
-        u8v.extend(cap.as_bytes().iter().map(|&b| b));
-        expand(&u8v, params, vars)
-    }
-
-    let caps = ["%d", "%c", "%s", "%Pa", "%l", "%!", "%~"];
-    for &cap in caps.iter() {
-        let res = get_res("", cap, &[], vars);
-        assert!(res.is_err(), "Op {} succeeded incorrectly with 0 stack entries", cap);
-        let p = if cap == "%s" || cap == "%l" { Words("foo".to_string()) } else { Number(97) };
-        let res = get_res("%p1", cap, &[p], vars);
-        assert!(res.is_ok(), "Op {} failed with 1 stack entry: {}", cap, res.unwrap_err());
-    }
-    let caps = ["%+", "%-", "%*", "%/", "%m", "%&", "%|", "%A", "%O"];
-    for &cap in caps.iter() {
-        let res = expand(cap.as_bytes(), &[], vars);
-        assert!(res.is_err(), "Binop {} succeeded incorrectly with 0 stack entries", cap);
-        let res = get_res("%{1}", cap, &[], vars);
-        assert!(res.is_err(), "Binop {} succeeded incorrectly with 1 stack entry", cap);
-        let res = get_res("%{1}%{2}", cap, &[], vars);
-        assert!(res.is_ok(), "Binop {} failed with 2 stack entries: {}", cap, res.unwrap_err());
-    }
-}
-
-#[test]
-fn test_push_bad_param() {
-    assert!(expand(b"%pa", &[], &mut Variables::new()).is_err());
-}
-
-#[test]
-fn test_comparison_ops() {
-    let v = [('<', [1u8, 0u8, 0u8]), ('=', [0u8, 1u8, 0u8]), ('>', [0u8, 0u8, 1u8])];
-    for &(op, bs) in v.iter() {
-        let s = format!("%{{1}}%{{2}}%{}%d", op);
-        let res = expand(s.as_bytes(), &[], &mut Variables::new());
-        assert!(res.is_ok(), "{}", res.unwrap_err());
-        assert_eq!(res.unwrap(), vec![b'0' + bs[0]]);
-        let s = format!("%{{1}}%{{1}}%{}%d", op);
-        let res = expand(s.as_bytes(), &[], &mut Variables::new());
-        assert!(res.is_ok(), "{}", res.unwrap_err());
-        assert_eq!(res.unwrap(), vec![b'0' + bs[1]]);
-        let s = format!("%{{2}}%{{1}}%{}%d", op);
-        let res = expand(s.as_bytes(), &[], &mut Variables::new());
-        assert!(res.is_ok(), "{}", res.unwrap_err());
-        assert_eq!(res.unwrap(), vec![b'0' + bs[2]]);
-    }
-}
-
-#[test]
-fn test_conditionals() {
-    let mut vars = Variables::new();
-    let s = b"\\E[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;m";
-    let res = expand(s, &[Number(1)], &mut vars);
-    assert!(res.is_ok(), "{}", res.unwrap_err());
-    assert_eq!(res.unwrap(), "\\E[31m".bytes().collect::<Vec<_>>());
-    let res = expand(s, &[Number(8)], &mut vars);
-    assert!(res.is_ok(), "{}", res.unwrap_err());
-    assert_eq!(res.unwrap(), "\\E[90m".bytes().collect::<Vec<_>>());
-    let res = expand(s, &[Number(42)], &mut vars);
-    assert!(res.is_ok(), "{}", res.unwrap_err());
-    assert_eq!(res.unwrap(), "\\E[38;5;42m".bytes().collect::<Vec<_>>());
-}
-
-#[test]
-fn test_format() {
-    let mut varstruct = Variables::new();
-    let vars = &mut varstruct;
-    assert_eq!(
-        expand(
-            b"%p1%s%p2%2s%p3%2s%p4%.2s",
-            &[
-                Words("foo".to_string()),
-                Words("foo".to_string()),
-                Words("f".to_string()),
-                Words("foo".to_string())
-            ],
-            vars
-        ),
-        Ok("foofoo ffo".bytes().collect::<Vec<_>>())
-    );
-    assert_eq!(
-        expand(b"%p1%:-4.2s", &[Words("foo".to_string())], vars),
-        Ok("fo  ".bytes().collect::<Vec<_>>())
-    );
-
-    assert_eq!(
-        expand(b"%p1%d%p1%.3d%p1%5d%p1%:+d", &[Number(1)], vars),
-        Ok("1001    1+1".bytes().collect::<Vec<_>>())
-    );
-    assert_eq!(
-        expand(b"%p1%o%p1%#o%p2%6.4x%p2%#6.4X", &[Number(15), Number(27)], vars),
-        Ok("17017  001b0X001B".bytes().collect::<Vec<_>>())
-    );
-}
diff --git a/library/term/src/terminfo/parser/compiled.rs b/library/term/src/terminfo/parser/compiled.rs
deleted file mode 100644 (file)
index fbc5aeb..0000000
+++ /dev/null
@@ -1,336 +0,0 @@
-#![allow(non_upper_case_globals, missing_docs)]
-
-//! ncurses-compatible compiled terminfo format parsing (term(5))
-
-use super::super::TermInfo;
-use std::collections::HashMap;
-use std::io;
-use std::io::prelude::*;
-
-#[cfg(test)]
-mod tests;
-
-// These are the orders ncurses uses in its compiled format (as of 5.9). Not sure if portable.
-
-#[rustfmt::skip]
-pub static boolfnames: &[&str] = &["auto_left_margin", "auto_right_margin",
-    "no_esc_ctlc", "ceol_standout_glitch", "eat_newline_glitch", "erase_overstrike", "generic_type",
-    "hard_copy", "has_meta_key", "has_status_line", "insert_null_glitch", "memory_above",
-    "memory_below", "move_insert_mode", "move_standout_mode", "over_strike", "status_line_esc_ok",
-    "dest_tabs_magic_smso", "tilde_glitch", "transparent_underline", "xon_xoff", "needs_xon_xoff",
-    "prtr_silent", "hard_cursor", "non_rev_rmcup", "no_pad_char", "non_dest_scroll_region",
-    "can_change", "back_color_erase", "hue_lightness_saturation", "col_addr_glitch",
-    "cr_cancels_micro_mode", "has_print_wheel", "row_addr_glitch", "semi_auto_right_margin",
-    "cpi_changes_res", "lpi_changes_res", "backspaces_with_bs", "crt_no_scrolling",
-    "no_correctly_working_cr", "gnu_has_meta_key", "linefeed_is_newline", "has_hardware_tabs",
-    "return_does_clr_eol"];
-
-#[rustfmt::skip]
-pub static boolnames: &[&str] = &["bw", "am", "xsb", "xhp", "xenl", "eo",
-    "gn", "hc", "km", "hs", "in", "db", "da", "mir", "msgr", "os", "eslok", "xt", "hz", "ul", "xon",
-    "nxon", "mc5i", "chts", "nrrmc", "npc", "ndscr", "ccc", "bce", "hls", "xhpa", "crxm", "daisy",
-    "xvpa", "sam", "cpix", "lpix", "OTbs", "OTns", "OTnc", "OTMT", "OTNL", "OTpt", "OTxr"];
-
-#[rustfmt::skip]
-pub static numfnames: &[&str] = &[ "columns", "init_tabs", "lines",
-    "lines_of_memory", "magic_cookie_glitch", "padding_baud_rate", "virtual_terminal",
-    "width_status_line", "num_labels", "label_height", "label_width", "max_attributes",
-    "maximum_windows", "max_colors", "max_pairs", "no_color_video", "buffer_capacity",
-    "dot_vert_spacing", "dot_horz_spacing", "max_micro_address", "max_micro_jump", "micro_col_size",
-    "micro_line_size", "number_of_pins", "output_res_char", "output_res_line",
-    "output_res_horz_inch", "output_res_vert_inch", "print_rate", "wide_char_size", "buttons",
-    "bit_image_entwining", "bit_image_type", "magic_cookie_glitch_ul", "carriage_return_delay",
-    "new_line_delay", "backspace_delay", "horizontal_tab_delay", "number_of_function_keys"];
-
-#[rustfmt::skip]
-pub static numnames: &[&str] = &[ "cols", "it", "lines", "lm", "xmc", "pb",
-    "vt", "wsl", "nlab", "lh", "lw", "ma", "wnum", "colors", "pairs", "ncv", "bufsz", "spinv",
-    "spinh", "maddr", "mjump", "mcs", "mls", "npins", "orc", "orl", "orhi", "orvi", "cps", "widcs",
-    "btns", "bitwin", "bitype", "UTug", "OTdC", "OTdN", "OTdB", "OTdT", "OTkn"];
-
-#[rustfmt::skip]
-pub static stringfnames: &[&str] = &[ "back_tab", "bell", "carriage_return",
-    "change_scroll_region", "clear_all_tabs", "clear_screen", "clr_eol", "clr_eos",
-    "column_address", "command_character", "cursor_address", "cursor_down", "cursor_home",
-    "cursor_invisible", "cursor_left", "cursor_mem_address", "cursor_normal", "cursor_right",
-    "cursor_to_ll", "cursor_up", "cursor_visible", "delete_character", "delete_line",
-    "dis_status_line", "down_half_line", "enter_alt_charset_mode", "enter_blink_mode",
-    "enter_bold_mode", "enter_ca_mode", "enter_delete_mode", "enter_dim_mode", "enter_insert_mode",
-    "enter_secure_mode", "enter_protected_mode", "enter_reverse_mode", "enter_standout_mode",
-    "enter_underline_mode", "erase_chars", "exit_alt_charset_mode", "exit_attribute_mode",
-    "exit_ca_mode", "exit_delete_mode", "exit_insert_mode", "exit_standout_mode",
-    "exit_underline_mode", "flash_screen", "form_feed", "from_status_line", "init_1string",
-    "init_2string", "init_3string", "init_file", "insert_character", "insert_line",
-    "insert_padding", "key_backspace", "key_catab", "key_clear", "key_ctab", "key_dc", "key_dl",
-    "key_down", "key_eic", "key_eol", "key_eos", "key_f0", "key_f1", "key_f10", "key_f2", "key_f3",
-    "key_f4", "key_f5", "key_f6", "key_f7", "key_f8", "key_f9", "key_home", "key_ic", "key_il",
-    "key_left", "key_ll", "key_npage", "key_ppage", "key_right", "key_sf", "key_sr", "key_stab",
-    "key_up", "keypad_local", "keypad_xmit", "lab_f0", "lab_f1", "lab_f10", "lab_f2", "lab_f3",
-    "lab_f4", "lab_f5", "lab_f6", "lab_f7", "lab_f8", "lab_f9", "meta_off", "meta_on", "newline",
-    "pad_char", "parm_dch", "parm_delete_line", "parm_down_cursor", "parm_ich", "parm_index",
-    "parm_insert_line", "parm_left_cursor", "parm_right_cursor", "parm_rindex", "parm_up_cursor",
-    "pkey_key", "pkey_local", "pkey_xmit", "print_screen", "prtr_off", "prtr_on", "repeat_char",
-    "reset_1string", "reset_2string", "reset_3string", "reset_file", "restore_cursor",
-    "row_address", "save_cursor", "scroll_forward", "scroll_reverse", "set_attributes", "set_tab",
-    "set_window", "tab", "to_status_line", "underline_char", "up_half_line", "init_prog", "key_a1",
-    "key_a3", "key_b2", "key_c1", "key_c3", "prtr_non", "char_padding", "acs_chars", "plab_norm",
-    "key_btab", "enter_xon_mode", "exit_xon_mode", "enter_am_mode", "exit_am_mode", "xon_character",
-    "xoff_character", "ena_acs", "label_on", "label_off", "key_beg", "key_cancel", "key_close",
-    "key_command", "key_copy", "key_create", "key_end", "key_enter", "key_exit", "key_find",
-    "key_help", "key_mark", "key_message", "key_move", "key_next", "key_open", "key_options",
-    "key_previous", "key_print", "key_redo", "key_reference", "key_refresh", "key_replace",
-    "key_restart", "key_resume", "key_save", "key_suspend", "key_undo", "key_sbeg", "key_scancel",
-    "key_scommand", "key_scopy", "key_screate", "key_sdc", "key_sdl", "key_select", "key_send",
-    "key_seol", "key_sexit", "key_sfind", "key_shelp", "key_shome", "key_sic", "key_sleft",
-    "key_smessage", "key_smove", "key_snext", "key_soptions", "key_sprevious", "key_sprint",
-    "key_sredo", "key_sreplace", "key_sright", "key_srsume", "key_ssave", "key_ssuspend",
-    "key_sundo", "req_for_input", "key_f11", "key_f12", "key_f13", "key_f14", "key_f15", "key_f16",
-    "key_f17", "key_f18", "key_f19", "key_f20", "key_f21", "key_f22", "key_f23", "key_f24",
-    "key_f25", "key_f26", "key_f27", "key_f28", "key_f29", "key_f30", "key_f31", "key_f32",
-    "key_f33", "key_f34", "key_f35", "key_f36", "key_f37", "key_f38", "key_f39", "key_f40",
-    "key_f41", "key_f42", "key_f43", "key_f44", "key_f45", "key_f46", "key_f47", "key_f48",
-    "key_f49", "key_f50", "key_f51", "key_f52", "key_f53", "key_f54", "key_f55", "key_f56",
-    "key_f57", "key_f58", "key_f59", "key_f60", "key_f61", "key_f62", "key_f63", "clr_bol",
-    "clear_margins", "set_left_margin", "set_right_margin", "label_format", "set_clock",
-    "display_clock", "remove_clock", "create_window", "goto_window", "hangup", "dial_phone",
-    "quick_dial", "tone", "pulse", "flash_hook", "fixed_pause", "wait_tone", "user0", "user1",
-    "user2", "user3", "user4", "user5", "user6", "user7", "user8", "user9", "orig_pair",
-    "orig_colors", "initialize_color", "initialize_pair", "set_color_pair", "set_foreground",
-    "set_background", "change_char_pitch", "change_line_pitch", "change_res_horz",
-    "change_res_vert", "define_char", "enter_doublewide_mode", "enter_draft_quality",
-    "enter_italics_mode", "enter_leftward_mode", "enter_micro_mode", "enter_near_letter_quality",
-    "enter_normal_quality", "enter_shadow_mode", "enter_subscript_mode", "enter_superscript_mode",
-    "enter_upward_mode", "exit_doublewide_mode", "exit_italics_mode", "exit_leftward_mode",
-    "exit_micro_mode", "exit_shadow_mode", "exit_subscript_mode", "exit_superscript_mode",
-    "exit_upward_mode", "micro_column_address", "micro_down", "micro_left", "micro_right",
-    "micro_row_address", "micro_up", "order_of_pins", "parm_down_micro", "parm_left_micro",
-    "parm_right_micro", "parm_up_micro", "select_char_set", "set_bottom_margin",
-    "set_bottom_margin_parm", "set_left_margin_parm", "set_right_margin_parm", "set_top_margin",
-    "set_top_margin_parm", "start_bit_image", "start_char_set_def", "stop_bit_image",
-    "stop_char_set_def", "subscript_characters", "superscript_characters", "these_cause_cr",
-    "zero_motion", "char_set_names", "key_mouse", "mouse_info", "req_mouse_pos", "get_mouse",
-    "set_a_foreground", "set_a_background", "pkey_plab", "device_type", "code_set_init",
-    "set0_des_seq", "set1_des_seq", "set2_des_seq", "set3_des_seq", "set_lr_margin",
-    "set_tb_margin", "bit_image_repeat", "bit_image_newline", "bit_image_carriage_return",
-    "color_names", "define_bit_image_region", "end_bit_image_region", "set_color_band",
-    "set_page_length", "display_pc_char", "enter_pc_charset_mode", "exit_pc_charset_mode",
-    "enter_scancode_mode", "exit_scancode_mode", "pc_term_options", "scancode_escape",
-    "alt_scancode_esc", "enter_horizontal_hl_mode", "enter_left_hl_mode", "enter_low_hl_mode",
-    "enter_right_hl_mode", "enter_top_hl_mode", "enter_vertical_hl_mode", "set_a_attributes",
-    "set_pglen_inch", "termcap_init2", "termcap_reset", "linefeed_if_not_lf", "backspace_if_not_bs",
-    "other_non_function_keys", "arrow_key_map", "acs_ulcorner", "acs_llcorner", "acs_urcorner",
-    "acs_lrcorner", "acs_ltee", "acs_rtee", "acs_btee", "acs_ttee", "acs_hline", "acs_vline",
-    "acs_plus", "memory_lock", "memory_unlock", "box_chars_1"];
-
-#[rustfmt::skip]
-pub static stringnames: &[&str] = &[ "cbt", "_", "cr", "csr", "tbc", "clear",
-    "_", "_", "hpa", "cmdch", "cup", "cud1", "home", "civis", "cub1", "mrcup", "cnorm", "cuf1",
-    "ll", "cuu1", "cvvis", "dch1", "dl1", "dsl", "hd", "smacs", "blink", "bold", "smcup", "smdc",
-    "dim", "smir", "invis", "prot", "rev", "smso", "smul", "ech", "rmacs", "sgr0", "rmcup", "rmdc",
-    "rmir", "rmso", "rmul", "flash", "ff", "fsl", "is1", "is2", "is3", "if", "ich1", "il1", "ip",
-    "kbs", "ktbc", "kclr", "kctab", "_", "_", "kcud1", "_", "_", "_", "_", "_", "_", "_", "_", "_",
-    "_", "_", "_", "_", "_", "khome", "_", "_", "kcub1", "_", "knp", "kpp", "kcuf1", "_", "_",
-    "khts", "_", "rmkx", "smkx", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "rmm", "_",
-    "_", "pad", "dch", "dl", "cud", "ich", "indn", "il", "cub", "cuf", "rin", "cuu", "pfkey",
-    "pfloc", "pfx", "mc0", "mc4", "_", "rep", "rs1", "rs2", "rs3", "rf", "rc", "vpa", "sc", "ind",
-    "ri", "sgr", "_", "wind", "_", "tsl", "uc", "hu", "iprog", "_", "_", "_", "_", "_", "mc5p",
-    "rmp", "acsc", "pln", "kcbt", "smxon", "rmxon", "smam", "rmam", "xonc", "xoffc", "_", "smln",
-    "rmln", "_", "kcan", "kclo", "kcmd", "kcpy", "kcrt", "_", "kent", "kext", "kfnd", "khlp",
-    "kmrk", "kmsg", "kmov", "knxt", "kopn", "kopt", "kprv", "kprt", "krdo", "kref", "krfr", "krpl",
-    "krst", "kres", "ksav", "kspd", "kund", "kBEG", "kCAN", "kCMD", "kCPY", "kCRT", "_", "_",
-    "kslt", "kEND", "kEOL", "kEXT", "kFND", "kHLP", "kHOM", "_", "kLFT", "kMSG", "kMOV", "kNXT",
-    "kOPT", "kPRV", "kPRT", "kRDO", "kRPL", "kRIT", "kRES", "kSAV", "kSPD", "kUND", "rfi", "_", "_",
-    "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_",
-    "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_",
-    "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_",
-    "dclk", "rmclk", "cwin", "wingo", "_", "dial", "qdial", "_", "_", "hook", "pause", "wait", "_",
-    "_", "_", "_", "_", "_", "_", "_", "_", "_", "op", "oc", "initc", "initp", "scp", "setf",
-    "setb", "cpi", "lpi", "chr", "cvr", "defc", "swidm", "sdrfq", "sitm", "slm", "smicm", "snlq",
-    "snrmq", "sshm", "ssubm", "ssupm", "sum", "rwidm", "ritm", "rlm", "rmicm", "rshm", "rsubm",
-    "rsupm", "rum", "mhpa", "mcud1", "mcub1", "mcuf1", "mvpa", "mcuu1", "porder", "mcud", "mcub",
-    "mcuf", "mcuu", "scs", "smgb", "smgbp", "smglp", "smgrp", "smgt", "smgtp", "sbim", "scsd",
-    "rbim", "rcsd", "subcs", "supcs", "docr", "zerom", "csnm", "kmous", "minfo", "reqmp", "getm",
-    "setaf", "setab", "pfxl", "devt", "csin", "s0ds", "s1ds", "s2ds", "s3ds", "smglr", "smgtb",
-    "birep", "binel", "bicr", "colornm", "defbi", "endbi", "setcolor", "slines", "dispc", "smpch",
-    "rmpch", "smsc", "rmsc", "pctrm", "scesc", "scesa", "ehhlm", "elhlm", "elohlm", "erhlm",
-    "ethlm", "evhlm", "sgr1", "slength", "OTi2", "OTrs", "OTnl", "OTbs", "OTko", "OTma", "OTG2",
-    "OTG3", "OTG1", "OTG4", "OTGR", "OTGL", "OTGU", "OTGD", "OTGH", "OTGV", "OTGC", "meml", "memu",
-    "box1"];
-
-fn read_le_u16(r: &mut dyn io::Read) -> io::Result<u16> {
-    let mut b = [0; 2];
-    r.read_exact(&mut b)?;
-    Ok((b[0] as u16) | ((b[1] as u16) << 8))
-}
-
-fn read_le_u32(r: &mut dyn io::Read) -> io::Result<u32> {
-    let mut b = [0; 4];
-    r.read_exact(&mut b)?;
-    Ok((b[0] as u32) | ((b[1] as u32) << 8) | ((b[2] as u32) << 16) | ((b[3] as u32) << 24))
-}
-
-fn read_byte(r: &mut dyn io::Read) -> io::Result<u8> {
-    match r.bytes().next() {
-        Some(s) => s,
-        None => Err(io::Error::new(io::ErrorKind::Other, "end of file")),
-    }
-}
-
-/// Parse a compiled terminfo entry, using long capability names if `longnames`
-/// is true
-pub fn parse(file: &mut dyn io::Read, longnames: bool) -> Result<TermInfo, String> {
-    macro_rules! t( ($e:expr) => (
-        match $e {
-            Ok(e) => e,
-            Err(e) => return Err(e.to_string())
-        }
-    ) );
-
-    let (bnames, snames, nnames) = if longnames {
-        (boolfnames, stringfnames, numfnames)
-    } else {
-        (boolnames, stringnames, numnames)
-    };
-
-    // Check magic number
-    let magic = t!(read_le_u16(file));
-
-    let extended = match magic {
-        0o0432 => false,
-        0o01036 => true,
-        _ => return Err(format!("invalid magic number, found {:o}", magic)),
-    };
-
-    // According to the spec, these fields must be >= -1 where -1 means that the feature is not
-    // supported. Using 0 instead of -1 works because we skip sections with length 0.
-    macro_rules! read_nonneg {
-        () => {{
-            match t!(read_le_u16(file)) as i16 {
-                n if n >= 0 => n as usize,
-                -1 => 0,
-                _ => return Err("incompatible file: length fields must be  >= -1".to_string()),
-            }
-        }};
-    }
-
-    let names_bytes = read_nonneg!();
-    let bools_bytes = read_nonneg!();
-    let numbers_count = read_nonneg!();
-    let string_offsets_count = read_nonneg!();
-    let string_table_bytes = read_nonneg!();
-
-    if names_bytes == 0 {
-        return Err("incompatible file: names field must be at least 1 byte wide".to_string());
-    }
-
-    if bools_bytes > boolnames.len() {
-        return Err("incompatible file: more booleans than expected".to_string());
-    }
-
-    if numbers_count > numnames.len() {
-        return Err("incompatible file: more numbers than expected".to_string());
-    }
-
-    if string_offsets_count > stringnames.len() {
-        return Err("incompatible file: more string offsets than expected".to_string());
-    }
-
-    // don't read NUL
-    let mut bytes = Vec::new();
-    t!(file.take((names_bytes - 1) as u64).read_to_end(&mut bytes));
-    let names_str = match String::from_utf8(bytes) {
-        Ok(s) => s,
-        Err(_) => return Err("input not utf-8".to_string()),
-    };
-
-    let term_names: Vec<String> = names_str.split('|').map(|s| s.to_string()).collect();
-    // consume NUL
-    if t!(read_byte(file)) != b'\0' {
-        return Err("incompatible file: missing null terminator for names section".to_string());
-    }
-
-    let bools_map: HashMap<String, bool> = t! {
-        (0..bools_bytes).filter_map(|i| match read_byte(file) {
-            Err(e) => Some(Err(e)),
-            Ok(1) => Some(Ok((bnames[i].to_string(), true))),
-            Ok(_) => None
-        }).collect()
-    };
-
-    if (bools_bytes + names_bytes) % 2 == 1 {
-        t!(read_byte(file)); // compensate for padding
-    }
-
-    let numbers_map: HashMap<String, u32> = t! {
-        (0..numbers_count).filter_map(|i| {
-            let number = if extended { read_le_u32(file) } else { read_le_u16(file).map(Into::into) };
-
-            match number {
-                Ok(0xFFFF) => None,
-                Ok(n) => Some(Ok((nnames[i].to_string(), n))),
-                Err(e) => Some(Err(e))
-            }
-        }).collect()
-    };
-
-    let string_map: HashMap<String, Vec<u8>> = if string_offsets_count > 0 {
-        let string_offsets: Vec<u16> =
-            t!((0..string_offsets_count).map(|_| read_le_u16(file)).collect());
-
-        let mut string_table = Vec::new();
-        t!(file.take(string_table_bytes as u64).read_to_end(&mut string_table));
-
-        t!(string_offsets
-            .into_iter()
-            .enumerate()
-            .filter(|&(_, offset)| {
-                // non-entry
-                offset != 0xFFFF
-            })
-            .map(|(i, offset)| {
-                let offset = offset as usize;
-
-                let name = if snames[i] == "_" { stringfnames[i] } else { snames[i] };
-
-                if offset == 0xFFFE {
-                    // undocumented: FFFE indicates cap@, which means the capability is not present
-                    // unsure if the handling for this is correct
-                    return Ok((name.to_string(), Vec::new()));
-                }
-
-                // Find the offset of the NUL we want to go to
-                let nulpos = string_table[offset..string_table_bytes].iter().position(|&b| b == 0);
-                match nulpos {
-                    Some(len) => {
-                        Ok((name.to_string(), string_table[offset..offset + len].to_vec()))
-                    }
-                    None => Err("invalid file: missing NUL in string_table".to_string()),
-                }
-            })
-            .collect())
-    } else {
-        HashMap::new()
-    };
-
-    // And that's all there is to it
-    Ok(TermInfo { names: term_names, bools: bools_map, numbers: numbers_map, strings: string_map })
-}
-
-/// Creates a dummy TermInfo struct for msys terminals
-pub fn msys_terminfo() -> TermInfo {
-    let mut strings = HashMap::new();
-    strings.insert("sgr0".to_string(), b"\x1B[0m".to_vec());
-    strings.insert("bold".to_string(), b"\x1B[1m".to_vec());
-    strings.insert("setaf".to_string(), b"\x1B[3%p1%dm".to_vec());
-    strings.insert("setab".to_string(), b"\x1B[4%p1%dm".to_vec());
-
-    let mut numbers = HashMap::new();
-    numbers.insert("colors".to_string(), 8);
-
-    TermInfo {
-        names: vec!["cygwin".to_string()], // msys is a fork of an older cygwin version
-        bools: HashMap::new(),
-        numbers,
-        strings,
-    }
-}
diff --git a/library/term/src/terminfo/parser/compiled/tests.rs b/library/term/src/terminfo/parser/compiled/tests.rs
deleted file mode 100644 (file)
index 8a9187b..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-use super::*;
-
-#[test]
-fn test_veclens() {
-    assert_eq!(boolfnames.len(), boolnames.len());
-    assert_eq!(numfnames.len(), numnames.len());
-    assert_eq!(stringfnames.len(), stringnames.len());
-}
diff --git a/library/term/src/terminfo/searcher.rs b/library/term/src/terminfo/searcher.rs
deleted file mode 100644 (file)
index 5499e24..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-//! ncurses-compatible database discovery.
-//!
-//! Does not support hashed database, only filesystem!
-
-use std::env;
-use std::fs;
-use std::path::PathBuf;
-
-#[cfg(test)]
-mod tests;
-
-/// Return path to database entry for `term`
-#[allow(deprecated)]
-pub fn get_dbpath_for_term(term: &str) -> Option<PathBuf> {
-    let mut dirs_to_search = Vec::new();
-    let first_char = term.chars().next()?;
-
-    // Find search directory
-    if let Some(dir) = env::var_os("TERMINFO") {
-        dirs_to_search.push(PathBuf::from(dir));
-    }
-
-    if let Ok(dirs) = env::var("TERMINFO_DIRS") {
-        for i in dirs.split(':') {
-            if i == "" {
-                dirs_to_search.push(PathBuf::from("/usr/share/terminfo"));
-            } else {
-                dirs_to_search.push(PathBuf::from(i));
-            }
-        }
-    } else {
-        // Found nothing in TERMINFO_DIRS, use the default paths:
-        // According to  /etc/terminfo/README, after looking at
-        // ~/.terminfo, ncurses will search /etc/terminfo, then
-        // /lib/terminfo, and eventually /usr/share/terminfo.
-        // On Haiku the database can be found at /boot/system/data/terminfo
-        if let Some(mut homedir) = env::home_dir() {
-            homedir.push(".terminfo");
-            dirs_to_search.push(homedir)
-        }
-
-        dirs_to_search.push(PathBuf::from("/etc/terminfo"));
-        dirs_to_search.push(PathBuf::from("/lib/terminfo"));
-        dirs_to_search.push(PathBuf::from("/usr/share/terminfo"));
-        dirs_to_search.push(PathBuf::from("/boot/system/data/terminfo"));
-    }
-
-    // Look for the terminal in all of the search directories
-    for mut p in dirs_to_search {
-        if fs::metadata(&p).is_ok() {
-            p.push(&first_char.to_string());
-            p.push(&term);
-            if fs::metadata(&p).is_ok() {
-                return Some(p);
-            }
-            p.pop();
-            p.pop();
-
-            // on some installations the dir is named after the hex of the char
-            // (e.g., macOS)
-            p.push(&format!("{:x}", first_char as usize));
-            p.push(term);
-            if fs::metadata(&p).is_ok() {
-                return Some(p);
-            }
-        }
-    }
-    None
-}
diff --git a/library/term/src/terminfo/searcher/tests.rs b/library/term/src/terminfo/searcher/tests.rs
deleted file mode 100644 (file)
index 4227a58..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-use super::*;
-
-#[test]
-#[ignore = "buildbots don't have ncurses installed and I can't mock everything I need"]
-fn test_get_dbpath_for_term() {
-    // woefully inadequate test coverage
-    // note: current tests won't work with non-standard terminfo hierarchies (e.g., macOS's)
-    use std::env;
-    // FIXME (#9639): This needs to handle non-utf8 paths
-    fn x(t: &str) -> String {
-        let p = get_dbpath_for_term(t).expect("no terminfo entry found");
-        p.to_str().unwrap().to_string()
-    }
-    assert!(x("screen") == "/usr/share/terminfo/s/screen");
-    assert!(get_dbpath_for_term("") == None);
-    env::set_var("TERMINFO_DIRS", ":");
-    assert!(x("screen") == "/usr/share/terminfo/s/screen");
-    env::remove_var("TERMINFO_DIRS");
-}
diff --git a/library/term/src/win.rs b/library/term/src/win.rs
deleted file mode 100644 (file)
index c24cf95..0000000
+++ /dev/null
@@ -1,220 +0,0 @@
-//! Windows console handling
-
-// FIXME (#13400): this is only a tiny fraction of the Windows console api
-
-use std::io;
-use std::io::prelude::*;
-
-use crate::color;
-use crate::Attr;
-use crate::Terminal;
-
-/// A Terminal implementation that uses the Win32 Console API.
-pub struct WinConsole<T> {
-    buf: T,
-    def_foreground: color::Color,
-    def_background: color::Color,
-    foreground: color::Color,
-    background: color::Color,
-}
-
-type SHORT = i16;
-type WORD = u16;
-type DWORD = u32;
-type BOOL = i32;
-type HANDLE = *mut u8;
-
-#[allow(non_snake_case)]
-#[repr(C)]
-struct SMALL_RECT {
-    Left: SHORT,
-    Top: SHORT,
-    Right: SHORT,
-    Bottom: SHORT,
-}
-
-#[allow(non_snake_case)]
-#[repr(C)]
-struct COORD {
-    X: SHORT,
-    Y: SHORT,
-}
-
-#[allow(non_snake_case)]
-#[repr(C)]
-struct CONSOLE_SCREEN_BUFFER_INFO {
-    dwSize: COORD,
-    dwCursorPosition: COORD,
-    wAttributes: WORD,
-    srWindow: SMALL_RECT,
-    dwMaximumWindowSize: COORD,
-}
-
-#[allow(non_snake_case)]
-#[link(name = "kernel32")]
-extern "system" {
-    fn SetConsoleTextAttribute(handle: HANDLE, attr: WORD) -> BOOL;
-    fn GetStdHandle(which: DWORD) -> HANDLE;
-    fn GetConsoleScreenBufferInfo(handle: HANDLE, info: *mut CONSOLE_SCREEN_BUFFER_INFO) -> BOOL;
-}
-
-fn color_to_bits(color: color::Color) -> u16 {
-    // magic numbers from mingw-w64's wincon.h
-
-    let bits = match color % 8 {
-        color::BLACK => 0,
-        color::BLUE => 0x1,
-        color::GREEN => 0x2,
-        color::RED => 0x4,
-        color::YELLOW => 0x2 | 0x4,
-        color::MAGENTA => 0x1 | 0x4,
-        color::CYAN => 0x1 | 0x2,
-        color::WHITE => 0x1 | 0x2 | 0x4,
-        _ => unreachable!(),
-    };
-
-    if color >= 8 { bits | 0x8 } else { bits }
-}
-
-fn bits_to_color(bits: u16) -> color::Color {
-    let color = match bits & 0x7 {
-        0 => color::BLACK,
-        0x1 => color::BLUE,
-        0x2 => color::GREEN,
-        0x4 => color::RED,
-        0x6 => color::YELLOW,
-        0x5 => color::MAGENTA,
-        0x3 => color::CYAN,
-        0x7 => color::WHITE,
-        _ => unreachable!(),
-    };
-
-    color | (u32::from(bits) & 0x8) // copy the hi-intensity bit
-}
-
-impl<T: Write + Send + 'static> WinConsole<T> {
-    fn apply(&mut self) {
-        let _unused = self.buf.flush();
-        let mut accum: WORD = 0;
-        accum |= color_to_bits(self.foreground);
-        accum |= color_to_bits(self.background) << 4;
-
-        unsafe {
-            // Magic -11 means stdout, from
-            // https://docs.microsoft.com/en-us/windows/console/getstdhandle
-            //
-            // You may be wondering, "but what about stderr?", and the answer
-            // to that is that setting terminal attributes on the stdout
-            // handle also sets them for stderr, since they go to the same
-            // terminal! Admittedly, this is fragile, since stderr could be
-            // redirected to a different console. This is good enough for
-            // rustc though. See #13400.
-            let out = GetStdHandle(-11i32 as DWORD);
-            SetConsoleTextAttribute(out, accum);
-        }
-    }
-
-    /// Returns `None` whenever the terminal cannot be created for some reason.
-    pub fn new(out: T) -> io::Result<WinConsole<T>> {
-        use std::mem::MaybeUninit;
-
-        let fg;
-        let bg;
-        unsafe {
-            let mut buffer_info = MaybeUninit::<CONSOLE_SCREEN_BUFFER_INFO>::uninit();
-            if GetConsoleScreenBufferInfo(GetStdHandle(-11i32 as DWORD), buffer_info.as_mut_ptr())
-                != 0
-            {
-                let buffer_info = buffer_info.assume_init();
-                fg = bits_to_color(buffer_info.wAttributes);
-                bg = bits_to_color(buffer_info.wAttributes >> 4);
-            } else {
-                fg = color::WHITE;
-                bg = color::BLACK;
-            }
-        }
-        Ok(WinConsole {
-            buf: out,
-            def_foreground: fg,
-            def_background: bg,
-            foreground: fg,
-            background: bg,
-        })
-    }
-}
-
-impl<T: Write> Write for WinConsole<T> {
-    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
-        self.buf.write(buf)
-    }
-
-    fn flush(&mut self) -> io::Result<()> {
-        self.buf.flush()
-    }
-}
-
-impl<T: Write + Send + 'static> Terminal for WinConsole<T> {
-    type Output = T;
-
-    fn fg(&mut self, color: color::Color) -> io::Result<bool> {
-        self.foreground = color;
-        self.apply();
-
-        Ok(true)
-    }
-
-    fn bg(&mut self, color: color::Color) -> io::Result<bool> {
-        self.background = color;
-        self.apply();
-
-        Ok(true)
-    }
-
-    fn attr(&mut self, attr: Attr) -> io::Result<bool> {
-        match attr {
-            Attr::ForegroundColor(f) => {
-                self.foreground = f;
-                self.apply();
-                Ok(true)
-            }
-            Attr::BackgroundColor(b) => {
-                self.background = b;
-                self.apply();
-                Ok(true)
-            }
-            _ => Ok(false),
-        }
-    }
-
-    fn supports_attr(&self, attr: Attr) -> bool {
-        // it claims support for underscore and reverse video, but I can't get
-        // it to do anything -cmr
-        match attr {
-            Attr::ForegroundColor(_) | Attr::BackgroundColor(_) => true,
-            _ => false,
-        }
-    }
-
-    fn reset(&mut self) -> io::Result<bool> {
-        self.foreground = self.def_foreground;
-        self.background = self.def_background;
-        self.apply();
-
-        Ok(true)
-    }
-
-    fn get_ref(&self) -> &T {
-        &self.buf
-    }
-
-    fn get_mut(&mut self) -> &mut T {
-        &mut self.buf
-    }
-
-    fn into_inner(self) -> T
-    where
-        Self: Sized,
-    {
-        self.buf
-    }
-}
index 226557430df210a23a1b24d309aa81a8d316ab41..479d86354c04cd24f84bcb938183e6630c31bd7a 100644 (file)
@@ -10,7 +10,6 @@ crate-type = ["dylib", "rlib"]
 [dependencies]
 cfg-if = { version = "0.1.8", features = ['rustc-dep-of-std'] }
 getopts = { version = "0.2.21", features = ['rustc-dep-of-std'] }
-term = { path = "../term" }
 std = { path = "../std" }
 core = { path = "../core" }
 libc = { version = "0.2", default-features = false }
index 9cfc7eaf4bcf459af5f471f963e1fa4b27bfd1ab..54e30a1fcd070424475b0dcdc661f29053bab207 100644 (file)
@@ -13,7 +13,7 @@
     formatters::{JsonFormatter, JunitFormatter, OutputFormatter, PrettyFormatter, TerseFormatter},
     helpers::{concurrency::get_concurrency, metrics::MetricMap},
     options::{Options, OutputFormat},
-    run_tests,
+    run_tests, term,
     test_result::TestResult,
     time::{TestExecTime, TestSuiteExecTime},
     types::{NamePadding, TestDesc, TestDescAndFn},
index e17fc08a9ae993b0a65eb150bf6d43308d145500..9cad71e30bddb85e8d78b798c70b8d32543339ca 100644 (file)
@@ -4,6 +4,7 @@
 use crate::{
     bench::fmt_bench_samples,
     console::{ConsoleTestState, OutputLocation},
+    term,
     test_result::TestResult,
     time,
     types::TestDesc,
index a2c223c494c293dca5c9ef13bb82269a47d1dded..0c8215c5daca165b71975d777ab1393a2aeeb700 100644 (file)
@@ -4,6 +4,7 @@
 use crate::{
     bench::fmt_bench_samples,
     console::{ConsoleTestState, OutputLocation},
+    term,
     test_result::TestResult,
     time,
     types::NamePadding,
index 3da4d434f48f23843e3ac3b2f588a51f94cae487..251f099f28af47e399640842f01c05fa4038837a 100644 (file)
@@ -20,7 +20,7 @@
 #![crate_name = "test"]
 #![unstable(feature = "test", issue = "50297")]
 #![doc(test(attr(deny(warnings))))]
-#![cfg_attr(unix, feature(libc))]
+#![feature(libc)]
 #![feature(rustc_private)]
 #![feature(nll)]
 #![feature(available_concurrency)]
@@ -80,6 +80,7 @@ pub mod test {
 mod helpers;
 mod options;
 pub mod stats;
+mod term;
 mod test_result;
 mod time;
 mod types;
diff --git a/library/test/src/term.rs b/library/test/src/term.rs
new file mode 100644 (file)
index 0000000..b256ab7
--- /dev/null
@@ -0,0 +1,85 @@
+//! Terminal formatting module.
+//!
+//! This module provides the `Terminal` trait, which abstracts over an [ANSI
+//! Terminal][ansi] to provide color printing, among other things. There are two
+//! implementations, the `TerminfoTerminal`, which uses control characters from
+//! a [terminfo][ti] database, and `WinConsole`, which uses the [Win32 Console
+//! API][win].
+//!
+//! [ansi]: https://en.wikipedia.org/wiki/ANSI_escape_code
+//! [win]: https://docs.microsoft.com/en-us/windows/console/character-mode-applications
+//! [ti]: https://en.wikipedia.org/wiki/Terminfo
+
+#![deny(missing_docs)]
+
+use std::io::{self, prelude::*};
+
+pub(crate) use terminfo::TerminfoTerminal;
+#[cfg(windows)]
+pub(crate) use win::WinConsole;
+
+pub(crate) mod terminfo;
+
+#[cfg(windows)]
+mod win;
+
+/// Alias for stdout terminals.
+pub(crate) type StdoutTerminal = dyn Terminal + Send;
+
+#[cfg(not(windows))]
+/// Returns a Terminal wrapping stdout, or None if a terminal couldn't be
+/// opened.
+pub(crate) fn stdout() -> Option<Box<StdoutTerminal>> {
+    TerminfoTerminal::new(io::stdout()).map(|t| Box::new(t) as Box<StdoutTerminal>)
+}
+
+#[cfg(windows)]
+/// Returns a Terminal wrapping stdout, or None if a terminal couldn't be
+/// opened.
+pub(crate) fn stdout() -> Option<Box<StdoutTerminal>> {
+    TerminfoTerminal::new(io::stdout())
+        .map(|t| Box::new(t) as Box<StdoutTerminal>)
+        .or_else(|| WinConsole::new(io::stdout()).ok().map(|t| Box::new(t) as Box<StdoutTerminal>))
+}
+
+/// Terminal color definitions
+#[allow(missing_docs)]
+#[cfg_attr(not(windows), allow(dead_code))]
+pub(crate) mod color {
+    /// Number for a terminal color
+    pub(crate) type Color = u32;
+
+    pub(crate) const BLACK: Color = 0;
+    pub(crate) const RED: Color = 1;
+    pub(crate) const GREEN: Color = 2;
+    pub(crate) const YELLOW: Color = 3;
+    pub(crate) const BLUE: Color = 4;
+    pub(crate) const MAGENTA: Color = 5;
+    pub(crate) const CYAN: Color = 6;
+    pub(crate) const WHITE: Color = 7;
+}
+
+/// A terminal with similar capabilities to an ANSI Terminal
+/// (foreground/background colors etc).
+pub trait Terminal: Write {
+    /// Sets the foreground color to the given color.
+    ///
+    /// If the color is a bright color, but the terminal only supports 8 colors,
+    /// the corresponding normal color will be used instead.
+    ///
+    /// Returns `Ok(true)` if the color was set, `Ok(false)` otherwise, and `Err(e)`
+    /// if there was an I/O error.
+    fn fg(&mut self, color: color::Color) -> io::Result<bool>;
+
+    /// Resets all terminal attributes and colors to their defaults.
+    ///
+    /// Returns `Ok(true)` if the terminal was reset, `Ok(false)` otherwise, and `Err(e)` if there
+    /// was an I/O error.
+    ///
+    /// *Note: This does not flush.*
+    ///
+    /// That means the reset command may get buffered so, if you aren't planning on doing anything
+    /// else that might flush stdout's buffer (e.g., writing a line of text), you should flush after
+    /// calling reset.
+    fn reset(&mut self) -> io::Result<bool>;
+}
diff --git a/library/test/src/term/terminfo/mod.rs b/library/test/src/term/terminfo/mod.rs
new file mode 100644 (file)
index 0000000..f4c5a05
--- /dev/null
@@ -0,0 +1,184 @@
+//! Terminfo database interface.
+
+use std::collections::HashMap;
+use std::env;
+use std::error;
+use std::fmt;
+use std::fs::File;
+use std::io::{self, prelude::*, BufReader};
+use std::path::Path;
+
+use super::color;
+use super::Terminal;
+
+use parm::{expand, Param, Variables};
+use parser::compiled::{msys_terminfo, parse};
+use searcher::get_dbpath_for_term;
+
+/// A parsed terminfo database entry.
+#[derive(Debug)]
+pub(crate) struct TermInfo {
+    /// Names for the terminal
+    pub(crate) names: Vec<String>,
+    /// Map of capability name to boolean value
+    pub(crate) bools: HashMap<String, bool>,
+    /// Map of capability name to numeric value
+    pub(crate) numbers: HashMap<String, u32>,
+    /// Map of capability name to raw (unexpanded) string
+    pub(crate) strings: HashMap<String, Vec<u8>>,
+}
+
+/// A terminfo creation error.
+#[derive(Debug)]
+pub(crate) enum Error {
+    /// TermUnset Indicates that the environment doesn't include enough information to find
+    /// the terminfo entry.
+    TermUnset,
+    /// MalformedTerminfo indicates that parsing the terminfo entry failed.
+    MalformedTerminfo(String),
+    /// io::Error forwards any io::Errors encountered when finding or reading the terminfo entry.
+    IoError(io::Error),
+}
+
+impl error::Error for Error {
+    fn source(&self) -> Option<&(dyn error::Error + 'static)> {
+        use Error::*;
+        match self {
+            IoError(e) => Some(e),
+            _ => None,
+        }
+    }
+}
+
+impl fmt::Display for Error {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        use Error::*;
+        match *self {
+            TermUnset => Ok(()),
+            MalformedTerminfo(ref e) => e.fmt(f),
+            IoError(ref e) => e.fmt(f),
+        }
+    }
+}
+
+impl TermInfo {
+    /// Creates a TermInfo based on current environment.
+    pub(crate) fn from_env() -> Result<TermInfo, Error> {
+        let term = match env::var("TERM") {
+            Ok(name) => TermInfo::from_name(&name),
+            Err(..) => return Err(Error::TermUnset),
+        };
+
+        if term.is_err() && env::var("MSYSCON").map_or(false, |s| "mintty.exe" == s) {
+            // msys terminal
+            Ok(msys_terminfo())
+        } else {
+            term
+        }
+    }
+
+    /// Creates a TermInfo for the named terminal.
+    pub(crate) fn from_name(name: &str) -> Result<TermInfo, Error> {
+        get_dbpath_for_term(name)
+            .ok_or_else(|| {
+                Error::IoError(io::Error::new(io::ErrorKind::NotFound, "terminfo file not found"))
+            })
+            .and_then(|p| TermInfo::from_path(&(*p)))
+    }
+
+    /// Parse the given TermInfo.
+    pub(crate) fn from_path<P: AsRef<Path>>(path: P) -> Result<TermInfo, Error> {
+        Self::_from_path(path.as_ref())
+    }
+    // Keep the metadata small
+    fn _from_path(path: &Path) -> Result<TermInfo, Error> {
+        let file = File::open(path).map_err(Error::IoError)?;
+        let mut reader = BufReader::new(file);
+        parse(&mut reader, false).map_err(Error::MalformedTerminfo)
+    }
+}
+
+pub(crate) mod searcher;
+
+/// TermInfo format parsing.
+pub(crate) mod parser {
+    //! ncurses-compatible compiled terminfo format parsing (term(5))
+    pub(crate) mod compiled;
+}
+pub(crate) mod parm;
+
+/// A Terminal that knows how many colors it supports, with a reference to its
+/// parsed Terminfo database record.
+pub(crate) struct TerminfoTerminal<T> {
+    num_colors: u32,
+    out: T,
+    ti: TermInfo,
+}
+
+impl<T: Write + Send> Terminal for TerminfoTerminal<T> {
+    fn fg(&mut self, color: color::Color) -> io::Result<bool> {
+        let color = self.dim_if_necessary(color);
+        if self.num_colors > color {
+            return self.apply_cap("setaf", &[Param::Number(color as i32)]);
+        }
+        Ok(false)
+    }
+
+    fn reset(&mut self) -> io::Result<bool> {
+        // are there any terminals that have color/attrs and not sgr0?
+        // Try falling back to sgr, then op
+        let cmd = match ["sgr0", "sgr", "op"].iter().find_map(|cap| self.ti.strings.get(*cap)) {
+            Some(op) => match expand(&op, &[], &mut Variables::new()) {
+                Ok(cmd) => cmd,
+                Err(e) => return Err(io::Error::new(io::ErrorKind::InvalidData, e)),
+            },
+            None => return Ok(false),
+        };
+        self.out.write_all(&cmd).and(Ok(true))
+    }
+}
+
+impl<T: Write + Send> TerminfoTerminal<T> {
+    /// Creates a new TerminfoTerminal with the given TermInfo and Write.
+    pub(crate) fn new_with_terminfo(out: T, terminfo: TermInfo) -> TerminfoTerminal<T> {
+        let nc = if terminfo.strings.contains_key("setaf") && terminfo.strings.contains_key("setab")
+        {
+            terminfo.numbers.get("colors").map_or(0, |&n| n)
+        } else {
+            0
+        };
+
+        TerminfoTerminal { out, ti: terminfo, num_colors: nc }
+    }
+
+    /// Creates a new TerminfoTerminal for the current environment with the given Write.
+    ///
+    /// Returns `None` when the terminfo cannot be found or parsed.
+    pub(crate) fn new(out: T) -> Option<TerminfoTerminal<T>> {
+        TermInfo::from_env().map(move |ti| TerminfoTerminal::new_with_terminfo(out, ti)).ok()
+    }
+
+    fn dim_if_necessary(&self, color: color::Color) -> color::Color {
+        if color >= self.num_colors && color >= 8 && color < 16 { color - 8 } else { color }
+    }
+
+    fn apply_cap(&mut self, cmd: &str, params: &[Param]) -> io::Result<bool> {
+        match self.ti.strings.get(cmd) {
+            Some(cmd) => match expand(&cmd, params, &mut Variables::new()) {
+                Ok(s) => self.out.write_all(&s).and(Ok(true)),
+                Err(e) => Err(io::Error::new(io::ErrorKind::InvalidData, e)),
+            },
+            None => Ok(false),
+        }
+    }
+}
+
+impl<T: Write> Write for TerminfoTerminal<T> {
+    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
+        self.out.write(buf)
+    }
+
+    fn flush(&mut self) -> io::Result<()> {
+        self.out.flush()
+    }
+}
diff --git a/library/test/src/term/terminfo/parm.rs b/library/test/src/term/terminfo/parm.rs
new file mode 100644 (file)
index 0000000..0d37eb7
--- /dev/null
@@ -0,0 +1,532 @@
+//! Parameterized string expansion
+
+use self::Param::*;
+use self::States::*;
+
+use std::iter::repeat;
+
+#[cfg(test)]
+mod tests;
+
+#[derive(Clone, Copy, PartialEq)]
+enum States {
+    Nothing,
+    Percent,
+    SetVar,
+    GetVar,
+    PushParam,
+    CharConstant,
+    CharClose,
+    IntConstant(i32),
+    FormatPattern(Flags, FormatState),
+    SeekIfElse(usize),
+    SeekIfElsePercent(usize),
+    SeekIfEnd(usize),
+    SeekIfEndPercent(usize),
+}
+
+#[derive(Copy, PartialEq, Clone)]
+enum FormatState {
+    Flags,
+    Width,
+    Precision,
+}
+
+/// Types of parameters a capability can use
+#[allow(missing_docs)]
+#[derive(Clone)]
+pub(crate) enum Param {
+    Number(i32),
+}
+
+/// Container for static and dynamic variable arrays
+pub(crate) struct Variables {
+    /// Static variables A-Z
+    sta_va: [Param; 26],
+    /// Dynamic variables a-z
+    dyn_va: [Param; 26],
+}
+
+impl Variables {
+    /// Returns a new zero-initialized Variables
+    pub(crate) fn new() -> Variables {
+        Variables {
+            sta_va: [
+                Number(0),
+                Number(0),
+                Number(0),
+                Number(0),
+                Number(0),
+                Number(0),
+                Number(0),
+                Number(0),
+                Number(0),
+                Number(0),
+                Number(0),
+                Number(0),
+                Number(0),
+                Number(0),
+                Number(0),
+                Number(0),
+                Number(0),
+                Number(0),
+                Number(0),
+                Number(0),
+                Number(0),
+                Number(0),
+                Number(0),
+                Number(0),
+                Number(0),
+                Number(0),
+            ],
+            dyn_va: [
+                Number(0),
+                Number(0),
+                Number(0),
+                Number(0),
+                Number(0),
+                Number(0),
+                Number(0),
+                Number(0),
+                Number(0),
+                Number(0),
+                Number(0),
+                Number(0),
+                Number(0),
+                Number(0),
+                Number(0),
+                Number(0),
+                Number(0),
+                Number(0),
+                Number(0),
+                Number(0),
+                Number(0),
+                Number(0),
+                Number(0),
+                Number(0),
+                Number(0),
+                Number(0),
+            ],
+        }
+    }
+}
+
+/// Expand a parameterized capability
+///
+/// # Arguments
+/// * `cap`    - string to expand
+/// * `params` - vector of params for %p1 etc
+/// * `vars`   - Variables struct for %Pa etc
+///
+/// To be compatible with ncurses, `vars` should be the same between calls to `expand` for
+/// multiple capabilities for the same terminal.
+pub(crate) fn expand(
+    cap: &[u8],
+    params: &[Param],
+    vars: &mut Variables,
+) -> Result<Vec<u8>, String> {
+    let mut state = Nothing;
+
+    // expanded cap will only rarely be larger than the cap itself
+    let mut output = Vec::with_capacity(cap.len());
+
+    let mut stack: Vec<Param> = Vec::new();
+
+    // Copy parameters into a local vector for mutability
+    let mut mparams = [
+        Number(0),
+        Number(0),
+        Number(0),
+        Number(0),
+        Number(0),
+        Number(0),
+        Number(0),
+        Number(0),
+        Number(0),
+    ];
+    for (dst, src) in mparams.iter_mut().zip(params.iter()) {
+        *dst = (*src).clone();
+    }
+
+    for &c in cap.iter() {
+        let cur = c as char;
+        let mut old_state = state;
+        match state {
+            Nothing => {
+                if cur == '%' {
+                    state = Percent;
+                } else {
+                    output.push(c);
+                }
+            }
+            Percent => {
+                match cur {
+                    '%' => {
+                        output.push(c);
+                        state = Nothing
+                    }
+                    'c' => {
+                        match stack.pop() {
+                            // if c is 0, use 0200 (128) for ncurses compatibility
+                            Some(Number(0)) => output.push(128u8),
+                            // Don't check bounds. ncurses just casts and truncates.
+                            Some(Number(c)) => output.push(c as u8),
+                            None => return Err("stack is empty".to_string()),
+                        }
+                    }
+                    'p' => state = PushParam,
+                    'P' => state = SetVar,
+                    'g' => state = GetVar,
+                    '\'' => state = CharConstant,
+                    '{' => state = IntConstant(0),
+                    'l' => match stack.pop() {
+                        Some(_) => return Err("a non-str was used with %l".to_string()),
+                        None => return Err("stack is empty".to_string()),
+                    },
+                    '+' | '-' | '/' | '*' | '^' | '&' | '|' | 'm' => {
+                        match (stack.pop(), stack.pop()) {
+                            (Some(Number(y)), Some(Number(x))) => stack.push(Number(match cur {
+                                '+' => x + y,
+                                '-' => x - y,
+                                '*' => x * y,
+                                '/' => x / y,
+                                '|' => x | y,
+                                '&' => x & y,
+                                '^' => x ^ y,
+                                'm' => x % y,
+                                _ => unreachable!("All cases handled"),
+                            })),
+                            _ => return Err("stack is empty".to_string()),
+                        }
+                    }
+                    '=' | '>' | '<' | 'A' | 'O' => match (stack.pop(), stack.pop()) {
+                        (Some(Number(y)), Some(Number(x))) => stack.push(Number(
+                            if match cur {
+                                '=' => x == y,
+                                '<' => x < y,
+                                '>' => x > y,
+                                'A' => x > 0 && y > 0,
+                                'O' => x > 0 || y > 0,
+                                _ => unreachable!(),
+                            } {
+                                1
+                            } else {
+                                0
+                            },
+                        )),
+                        _ => return Err("stack is empty".to_string()),
+                    },
+                    '!' | '~' => match stack.pop() {
+                        Some(Number(x)) => stack.push(Number(match cur {
+                            '!' if x > 0 => 0,
+                            '!' => 1,
+                            '~' => !x,
+                            _ => unreachable!(),
+                        })),
+                        None => return Err("stack is empty".to_string()),
+                    },
+                    'i' => match (&mparams[0], &mparams[1]) {
+                        (&Number(x), &Number(y)) => {
+                            mparams[0] = Number(x + 1);
+                            mparams[1] = Number(y + 1);
+                        }
+                    },
+
+                    // printf-style support for %doxXs
+                    'd' | 'o' | 'x' | 'X' | 's' => {
+                        if let Some(arg) = stack.pop() {
+                            let flags = Flags::new();
+                            let res = format(arg, FormatOp::from_char(cur), flags)?;
+                            output.extend(res.iter().cloned());
+                        } else {
+                            return Err("stack is empty".to_string());
+                        }
+                    }
+                    ':' | '#' | ' ' | '.' | '0'..='9' => {
+                        let mut flags = Flags::new();
+                        let mut fstate = FormatState::Flags;
+                        match cur {
+                            ':' => (),
+                            '#' => flags.alternate = true,
+                            ' ' => flags.space = true,
+                            '.' => fstate = FormatState::Precision,
+                            '0'..='9' => {
+                                flags.width = cur as usize - '0' as usize;
+                                fstate = FormatState::Width;
+                            }
+                            _ => unreachable!(),
+                        }
+                        state = FormatPattern(flags, fstate);
+                    }
+
+                    // conditionals
+                    '?' => (),
+                    't' => match stack.pop() {
+                        Some(Number(0)) => state = SeekIfElse(0),
+                        Some(Number(_)) => (),
+                        None => return Err("stack is empty".to_string()),
+                    },
+                    'e' => state = SeekIfEnd(0),
+                    ';' => (),
+                    _ => return Err(format!("unrecognized format option {}", cur)),
+                }
+            }
+            PushParam => {
+                // params are 1-indexed
+                stack.push(
+                    mparams[match cur.to_digit(10) {
+                        Some(d) => d as usize - 1,
+                        None => return Err("bad param number".to_string()),
+                    }]
+                    .clone(),
+                );
+            }
+            SetVar => {
+                if cur >= 'A' && cur <= 'Z' {
+                    if let Some(arg) = stack.pop() {
+                        let idx = (cur as u8) - b'A';
+                        vars.sta_va[idx as usize] = arg;
+                    } else {
+                        return Err("stack is empty".to_string());
+                    }
+                } else if cur >= 'a' && cur <= 'z' {
+                    if let Some(arg) = stack.pop() {
+                        let idx = (cur as u8) - b'a';
+                        vars.dyn_va[idx as usize] = arg;
+                    } else {
+                        return Err("stack is empty".to_string());
+                    }
+                } else {
+                    return Err("bad variable name in %P".to_string());
+                }
+            }
+            GetVar => {
+                if cur >= 'A' && cur <= 'Z' {
+                    let idx = (cur as u8) - b'A';
+                    stack.push(vars.sta_va[idx as usize].clone());
+                } else if cur >= 'a' && cur <= 'z' {
+                    let idx = (cur as u8) - b'a';
+                    stack.push(vars.dyn_va[idx as usize].clone());
+                } else {
+                    return Err("bad variable name in %g".to_string());
+                }
+            }
+            CharConstant => {
+                stack.push(Number(c as i32));
+                state = CharClose;
+            }
+            CharClose => {
+                if cur != '\'' {
+                    return Err("malformed character constant".to_string());
+                }
+            }
+            IntConstant(i) => {
+                if cur == '}' {
+                    stack.push(Number(i));
+                    state = Nothing;
+                } else if let Some(digit) = cur.to_digit(10) {
+                    match i.checked_mul(10).and_then(|i_ten| i_ten.checked_add(digit as i32)) {
+                        Some(i) => {
+                            state = IntConstant(i);
+                            old_state = Nothing;
+                        }
+                        None => return Err("int constant too large".to_string()),
+                    }
+                } else {
+                    return Err("bad int constant".to_string());
+                }
+            }
+            FormatPattern(ref mut flags, ref mut fstate) => {
+                old_state = Nothing;
+                match (*fstate, cur) {
+                    (_, 'd') | (_, 'o') | (_, 'x') | (_, 'X') | (_, 's') => {
+                        if let Some(arg) = stack.pop() {
+                            let res = format(arg, FormatOp::from_char(cur), *flags)?;
+                            output.extend(res.iter().cloned());
+                            // will cause state to go to Nothing
+                            old_state = FormatPattern(*flags, *fstate);
+                        } else {
+                            return Err("stack is empty".to_string());
+                        }
+                    }
+                    (FormatState::Flags, '#') => {
+                        flags.alternate = true;
+                    }
+                    (FormatState::Flags, '-') => {
+                        flags.left = true;
+                    }
+                    (FormatState::Flags, '+') => {
+                        flags.sign = true;
+                    }
+                    (FormatState::Flags, ' ') => {
+                        flags.space = true;
+                    }
+                    (FormatState::Flags, '0'..='9') => {
+                        flags.width = cur as usize - '0' as usize;
+                        *fstate = FormatState::Width;
+                    }
+                    (FormatState::Flags, '.') => {
+                        *fstate = FormatState::Precision;
+                    }
+                    (FormatState::Width, '0'..='9') => {
+                        let old = flags.width;
+                        flags.width = flags.width * 10 + (cur as usize - '0' as usize);
+                        if flags.width < old {
+                            return Err("format width overflow".to_string());
+                        }
+                    }
+                    (FormatState::Width, '.') => {
+                        *fstate = FormatState::Precision;
+                    }
+                    (FormatState::Precision, '0'..='9') => {
+                        let old = flags.precision;
+                        flags.precision = flags.precision * 10 + (cur as usize - '0' as usize);
+                        if flags.precision < old {
+                            return Err("format precision overflow".to_string());
+                        }
+                    }
+                    _ => return Err("invalid format specifier".to_string()),
+                }
+            }
+            SeekIfElse(level) => {
+                if cur == '%' {
+                    state = SeekIfElsePercent(level);
+                }
+                old_state = Nothing;
+            }
+            SeekIfElsePercent(level) => {
+                if cur == ';' {
+                    if level == 0 {
+                        state = Nothing;
+                    } else {
+                        state = SeekIfElse(level - 1);
+                    }
+                } else if cur == 'e' && level == 0 {
+                    state = Nothing;
+                } else if cur == '?' {
+                    state = SeekIfElse(level + 1);
+                } else {
+                    state = SeekIfElse(level);
+                }
+            }
+            SeekIfEnd(level) => {
+                if cur == '%' {
+                    state = SeekIfEndPercent(level);
+                }
+                old_state = Nothing;
+            }
+            SeekIfEndPercent(level) => {
+                if cur == ';' {
+                    if level == 0 {
+                        state = Nothing;
+                    } else {
+                        state = SeekIfEnd(level - 1);
+                    }
+                } else if cur == '?' {
+                    state = SeekIfEnd(level + 1);
+                } else {
+                    state = SeekIfEnd(level);
+                }
+            }
+        }
+        if state == old_state {
+            state = Nothing;
+        }
+    }
+    Ok(output)
+}
+
+#[derive(Copy, PartialEq, Clone)]
+struct Flags {
+    width: usize,
+    precision: usize,
+    alternate: bool,
+    left: bool,
+    sign: bool,
+    space: bool,
+}
+
+impl Flags {
+    fn new() -> Flags {
+        Flags { width: 0, precision: 0, alternate: false, left: false, sign: false, space: false }
+    }
+}
+
+#[derive(Copy, Clone)]
+enum FormatOp {
+    Digit,
+    Octal,
+    LowerHex,
+    UpperHex,
+    String,
+}
+
+impl FormatOp {
+    fn from_char(c: char) -> FormatOp {
+        match c {
+            'd' => FormatOp::Digit,
+            'o' => FormatOp::Octal,
+            'x' => FormatOp::LowerHex,
+            'X' => FormatOp::UpperHex,
+            's' => FormatOp::String,
+            _ => panic!("bad FormatOp char"),
+        }
+    }
+}
+
+fn format(val: Param, op: FormatOp, flags: Flags) -> Result<Vec<u8>, String> {
+    let mut s = match val {
+        Number(d) => {
+            match op {
+                FormatOp::Digit => {
+                    if flags.sign {
+                        format!("{:+01$}", d, flags.precision)
+                    } else if d < 0 {
+                        // C doesn't take sign into account in precision calculation.
+                        format!("{:01$}", d, flags.precision + 1)
+                    } else if flags.space {
+                        format!(" {:01$}", d, flags.precision)
+                    } else {
+                        format!("{:01$}", d, flags.precision)
+                    }
+                }
+                FormatOp::Octal => {
+                    if flags.alternate {
+                        // Leading octal zero counts against precision.
+                        format!("0{:01$o}", d, flags.precision.saturating_sub(1))
+                    } else {
+                        format!("{:01$o}", d, flags.precision)
+                    }
+                }
+                FormatOp::LowerHex => {
+                    if flags.alternate && d != 0 {
+                        format!("0x{:01$x}", d, flags.precision)
+                    } else {
+                        format!("{:01$x}", d, flags.precision)
+                    }
+                }
+                FormatOp::UpperHex => {
+                    if flags.alternate && d != 0 {
+                        format!("0X{:01$X}", d, flags.precision)
+                    } else {
+                        format!("{:01$X}", d, flags.precision)
+                    }
+                }
+                FormatOp::String => return Err("non-number on stack with %s".to_string()),
+            }
+            .into_bytes()
+        }
+    };
+    if flags.width > s.len() {
+        let n = flags.width - s.len();
+        if flags.left {
+            s.extend(repeat(b' ').take(n));
+        } else {
+            let mut s_ = Vec::with_capacity(flags.width);
+            s_.extend(repeat(b' ').take(n));
+            s_.extend(s.into_iter());
+            s = s_;
+        }
+    }
+    Ok(s)
+}
diff --git a/library/test/src/term/terminfo/parm/tests.rs b/library/test/src/term/terminfo/parm/tests.rs
new file mode 100644 (file)
index 0000000..256d1aa
--- /dev/null
@@ -0,0 +1,124 @@
+use super::*;
+
+use std::result::Result::Ok;
+
+#[test]
+fn test_basic_setabf() {
+    let s = b"\\E[48;5;%p1%dm";
+    assert_eq!(
+        expand(s, &[Number(1)], &mut Variables::new()).unwrap(),
+        "\\E[48;5;1m".bytes().collect::<Vec<_>>()
+    );
+}
+
+#[test]
+fn test_multiple_int_constants() {
+    assert_eq!(
+        expand(b"%{1}%{2}%d%d", &[], &mut Variables::new()).unwrap(),
+        "21".bytes().collect::<Vec<_>>()
+    );
+}
+
+#[test]
+fn test_op_i() {
+    let mut vars = Variables::new();
+    assert_eq!(
+        expand(b"%p1%d%p2%d%p3%d%i%p1%d%p2%d%p3%d", &[Number(1), Number(2), Number(3)], &mut vars),
+        Ok("123233".bytes().collect::<Vec<_>>())
+    );
+    assert_eq!(
+        expand(b"%p1%d%p2%d%i%p1%d%p2%d", &[], &mut vars),
+        Ok("0011".bytes().collect::<Vec<_>>())
+    );
+}
+
+#[test]
+fn test_param_stack_failure_conditions() {
+    let mut varstruct = Variables::new();
+    let vars = &mut varstruct;
+    fn get_res(
+        fmt: &str,
+        cap: &str,
+        params: &[Param],
+        vars: &mut Variables,
+    ) -> Result<Vec<u8>, String> {
+        let mut u8v: Vec<_> = fmt.bytes().collect();
+        u8v.extend(cap.as_bytes().iter().map(|&b| b));
+        expand(&u8v, params, vars)
+    }
+
+    let caps = ["%d", "%c", "%s", "%Pa", "%l", "%!", "%~"];
+    for &cap in caps.iter() {
+        let res = get_res("", cap, &[], vars);
+        assert!(res.is_err(), "Op {} succeeded incorrectly with 0 stack entries", cap);
+        if cap == "%s" || cap == "%l" {
+            continue;
+        }
+        let p = Number(97);
+        let res = get_res("%p1", cap, &[p], vars);
+        assert!(res.is_ok(), "Op {} failed with 1 stack entry: {}", cap, res.unwrap_err());
+    }
+    let caps = ["%+", "%-", "%*", "%/", "%m", "%&", "%|", "%A", "%O"];
+    for &cap in caps.iter() {
+        let res = expand(cap.as_bytes(), &[], vars);
+        assert!(res.is_err(), "Binop {} succeeded incorrectly with 0 stack entries", cap);
+        let res = get_res("%{1}", cap, &[], vars);
+        assert!(res.is_err(), "Binop {} succeeded incorrectly with 1 stack entry", cap);
+        let res = get_res("%{1}%{2}", cap, &[], vars);
+        assert!(res.is_ok(), "Binop {} failed with 2 stack entries: {}", cap, res.unwrap_err());
+    }
+}
+
+#[test]
+fn test_push_bad_param() {
+    assert!(expand(b"%pa", &[], &mut Variables::new()).is_err());
+}
+
+#[test]
+fn test_comparison_ops() {
+    let v = [('<', [1u8, 0u8, 0u8]), ('=', [0u8, 1u8, 0u8]), ('>', [0u8, 0u8, 1u8])];
+    for &(op, bs) in v.iter() {
+        let s = format!("%{{1}}%{{2}}%{}%d", op);
+        let res = expand(s.as_bytes(), &[], &mut Variables::new());
+        assert!(res.is_ok(), "{}", res.unwrap_err());
+        assert_eq!(res.unwrap(), vec![b'0' + bs[0]]);
+        let s = format!("%{{1}}%{{1}}%{}%d", op);
+        let res = expand(s.as_bytes(), &[], &mut Variables::new());
+        assert!(res.is_ok(), "{}", res.unwrap_err());
+        assert_eq!(res.unwrap(), vec![b'0' + bs[1]]);
+        let s = format!("%{{2}}%{{1}}%{}%d", op);
+        let res = expand(s.as_bytes(), &[], &mut Variables::new());
+        assert!(res.is_ok(), "{}", res.unwrap_err());
+        assert_eq!(res.unwrap(), vec![b'0' + bs[2]]);
+    }
+}
+
+#[test]
+fn test_conditionals() {
+    let mut vars = Variables::new();
+    let s = b"\\E[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;m";
+    let res = expand(s, &[Number(1)], &mut vars);
+    assert!(res.is_ok(), "{}", res.unwrap_err());
+    assert_eq!(res.unwrap(), "\\E[31m".bytes().collect::<Vec<_>>());
+    let res = expand(s, &[Number(8)], &mut vars);
+    assert!(res.is_ok(), "{}", res.unwrap_err());
+    assert_eq!(res.unwrap(), "\\E[90m".bytes().collect::<Vec<_>>());
+    let res = expand(s, &[Number(42)], &mut vars);
+    assert!(res.is_ok(), "{}", res.unwrap_err());
+    assert_eq!(res.unwrap(), "\\E[38;5;42m".bytes().collect::<Vec<_>>());
+}
+
+#[test]
+fn test_format() {
+    let mut varstruct = Variables::new();
+    let vars = &mut varstruct;
+
+    assert_eq!(
+        expand(b"%p1%d%p1%.3d%p1%5d%p1%:+d", &[Number(1)], vars),
+        Ok("1001    1+1".bytes().collect::<Vec<_>>())
+    );
+    assert_eq!(
+        expand(b"%p1%o%p1%#o%p2%6.4x%p2%#6.4X", &[Number(15), Number(27)], vars),
+        Ok("17017  001b0X001B".bytes().collect::<Vec<_>>())
+    );
+}
diff --git a/library/test/src/term/terminfo/parser/compiled.rs b/library/test/src/term/terminfo/parser/compiled.rs
new file mode 100644 (file)
index 0000000..b24f3f8
--- /dev/null
@@ -0,0 +1,336 @@
+#![allow(non_upper_case_globals, missing_docs)]
+
+//! ncurses-compatible compiled terminfo format parsing (term(5))
+
+use super::super::TermInfo;
+use std::collections::HashMap;
+use std::io;
+use std::io::prelude::*;
+
+#[cfg(test)]
+mod tests;
+
+// These are the orders ncurses uses in its compiled format (as of 5.9). Not sure if portable.
+
+#[rustfmt::skip]
+pub(crate) static boolfnames: &[&str] = &["auto_left_margin", "auto_right_margin",
+    "no_esc_ctlc", "ceol_standout_glitch", "eat_newline_glitch", "erase_overstrike", "generic_type",
+    "hard_copy", "has_meta_key", "has_status_line", "insert_null_glitch", "memory_above",
+    "memory_below", "move_insert_mode", "move_standout_mode", "over_strike", "status_line_esc_ok",
+    "dest_tabs_magic_smso", "tilde_glitch", "transparent_underline", "xon_xoff", "needs_xon_xoff",
+    "prtr_silent", "hard_cursor", "non_rev_rmcup", "no_pad_char", "non_dest_scroll_region",
+    "can_change", "back_color_erase", "hue_lightness_saturation", "col_addr_glitch",
+    "cr_cancels_micro_mode", "has_print_wheel", "row_addr_glitch", "semi_auto_right_margin",
+    "cpi_changes_res", "lpi_changes_res", "backspaces_with_bs", "crt_no_scrolling",
+    "no_correctly_working_cr", "gnu_has_meta_key", "linefeed_is_newline", "has_hardware_tabs",
+    "return_does_clr_eol"];
+
+#[rustfmt::skip]
+pub(crate) static boolnames: &[&str] = &["bw", "am", "xsb", "xhp", "xenl", "eo",
+    "gn", "hc", "km", "hs", "in", "db", "da", "mir", "msgr", "os", "eslok", "xt", "hz", "ul", "xon",
+    "nxon", "mc5i", "chts", "nrrmc", "npc", "ndscr", "ccc", "bce", "hls", "xhpa", "crxm", "daisy",
+    "xvpa", "sam", "cpix", "lpix", "OTbs", "OTns", "OTnc", "OTMT", "OTNL", "OTpt", "OTxr"];
+
+#[rustfmt::skip]
+pub(crate) static numfnames: &[&str] = &[ "columns", "init_tabs", "lines",
+    "lines_of_memory", "magic_cookie_glitch", "padding_baud_rate", "virtual_terminal",
+    "width_status_line", "num_labels", "label_height", "label_width", "max_attributes",
+    "maximum_windows", "max_colors", "max_pairs", "no_color_video", "buffer_capacity",
+    "dot_vert_spacing", "dot_horz_spacing", "max_micro_address", "max_micro_jump", "micro_col_size",
+    "micro_line_size", "number_of_pins", "output_res_char", "output_res_line",
+    "output_res_horz_inch", "output_res_vert_inch", "print_rate", "wide_char_size", "buttons",
+    "bit_image_entwining", "bit_image_type", "magic_cookie_glitch_ul", "carriage_return_delay",
+    "new_line_delay", "backspace_delay", "horizontal_tab_delay", "number_of_function_keys"];
+
+#[rustfmt::skip]
+pub(crate) static numnames: &[&str] = &[ "cols", "it", "lines", "lm", "xmc", "pb",
+    "vt", "wsl", "nlab", "lh", "lw", "ma", "wnum", "colors", "pairs", "ncv", "bufsz", "spinv",
+    "spinh", "maddr", "mjump", "mcs", "mls", "npins", "orc", "orl", "orhi", "orvi", "cps", "widcs",
+    "btns", "bitwin", "bitype", "UTug", "OTdC", "OTdN", "OTdB", "OTdT", "OTkn"];
+
+#[rustfmt::skip]
+pub(crate) static stringfnames: &[&str] = &[ "back_tab", "bell", "carriage_return",
+    "change_scroll_region", "clear_all_tabs", "clear_screen", "clr_eol", "clr_eos",
+    "column_address", "command_character", "cursor_address", "cursor_down", "cursor_home",
+    "cursor_invisible", "cursor_left", "cursor_mem_address", "cursor_normal", "cursor_right",
+    "cursor_to_ll", "cursor_up", "cursor_visible", "delete_character", "delete_line",
+    "dis_status_line", "down_half_line", "enter_alt_charset_mode", "enter_blink_mode",
+    "enter_bold_mode", "enter_ca_mode", "enter_delete_mode", "enter_dim_mode", "enter_insert_mode",
+    "enter_secure_mode", "enter_protected_mode", "enter_reverse_mode", "enter_standout_mode",
+    "enter_underline_mode", "erase_chars", "exit_alt_charset_mode", "exit_attribute_mode",
+    "exit_ca_mode", "exit_delete_mode", "exit_insert_mode", "exit_standout_mode",
+    "exit_underline_mode", "flash_screen", "form_feed", "from_status_line", "init_1string",
+    "init_2string", "init_3string", "init_file", "insert_character", "insert_line",
+    "insert_padding", "key_backspace", "key_catab", "key_clear", "key_ctab", "key_dc", "key_dl",
+    "key_down", "key_eic", "key_eol", "key_eos", "key_f0", "key_f1", "key_f10", "key_f2", "key_f3",
+    "key_f4", "key_f5", "key_f6", "key_f7", "key_f8", "key_f9", "key_home", "key_ic", "key_il",
+    "key_left", "key_ll", "key_npage", "key_ppage", "key_right", "key_sf", "key_sr", "key_stab",
+    "key_up", "keypad_local", "keypad_xmit", "lab_f0", "lab_f1", "lab_f10", "lab_f2", "lab_f3",
+    "lab_f4", "lab_f5", "lab_f6", "lab_f7", "lab_f8", "lab_f9", "meta_off", "meta_on", "newline",
+    "pad_char", "parm_dch", "parm_delete_line", "parm_down_cursor", "parm_ich", "parm_index",
+    "parm_insert_line", "parm_left_cursor", "parm_right_cursor", "parm_rindex", "parm_up_cursor",
+    "pkey_key", "pkey_local", "pkey_xmit", "print_screen", "prtr_off", "prtr_on", "repeat_char",
+    "reset_1string", "reset_2string", "reset_3string", "reset_file", "restore_cursor",
+    "row_address", "save_cursor", "scroll_forward", "scroll_reverse", "set_attributes", "set_tab",
+    "set_window", "tab", "to_status_line", "underline_char", "up_half_line", "init_prog", "key_a1",
+    "key_a3", "key_b2", "key_c1", "key_c3", "prtr_non", "char_padding", "acs_chars", "plab_norm",
+    "key_btab", "enter_xon_mode", "exit_xon_mode", "enter_am_mode", "exit_am_mode", "xon_character",
+    "xoff_character", "ena_acs", "label_on", "label_off", "key_beg", "key_cancel", "key_close",
+    "key_command", "key_copy", "key_create", "key_end", "key_enter", "key_exit", "key_find",
+    "key_help", "key_mark", "key_message", "key_move", "key_next", "key_open", "key_options",
+    "key_previous", "key_print", "key_redo", "key_reference", "key_refresh", "key_replace",
+    "key_restart", "key_resume", "key_save", "key_suspend", "key_undo", "key_sbeg", "key_scancel",
+    "key_scommand", "key_scopy", "key_screate", "key_sdc", "key_sdl", "key_select", "key_send",
+    "key_seol", "key_sexit", "key_sfind", "key_shelp", "key_shome", "key_sic", "key_sleft",
+    "key_smessage", "key_smove", "key_snext", "key_soptions", "key_sprevious", "key_sprint",
+    "key_sredo", "key_sreplace", "key_sright", "key_srsume", "key_ssave", "key_ssuspend",
+    "key_sundo", "req_for_input", "key_f11", "key_f12", "key_f13", "key_f14", "key_f15", "key_f16",
+    "key_f17", "key_f18", "key_f19", "key_f20", "key_f21", "key_f22", "key_f23", "key_f24",
+    "key_f25", "key_f26", "key_f27", "key_f28", "key_f29", "key_f30", "key_f31", "key_f32",
+    "key_f33", "key_f34", "key_f35", "key_f36", "key_f37", "key_f38", "key_f39", "key_f40",
+    "key_f41", "key_f42", "key_f43", "key_f44", "key_f45", "key_f46", "key_f47", "key_f48",
+    "key_f49", "key_f50", "key_f51", "key_f52", "key_f53", "key_f54", "key_f55", "key_f56",
+    "key_f57", "key_f58", "key_f59", "key_f60", "key_f61", "key_f62", "key_f63", "clr_bol",
+    "clear_margins", "set_left_margin", "set_right_margin", "label_format", "set_clock",
+    "display_clock", "remove_clock", "create_window", "goto_window", "hangup", "dial_phone",
+    "quick_dial", "tone", "pulse", "flash_hook", "fixed_pause", "wait_tone", "user0", "user1",
+    "user2", "user3", "user4", "user5", "user6", "user7", "user8", "user9", "orig_pair",
+    "orig_colors", "initialize_color", "initialize_pair", "set_color_pair", "set_foreground",
+    "set_background", "change_char_pitch", "change_line_pitch", "change_res_horz",
+    "change_res_vert", "define_char", "enter_doublewide_mode", "enter_draft_quality",
+    "enter_italics_mode", "enter_leftward_mode", "enter_micro_mode", "enter_near_letter_quality",
+    "enter_normal_quality", "enter_shadow_mode", "enter_subscript_mode", "enter_superscript_mode",
+    "enter_upward_mode", "exit_doublewide_mode", "exit_italics_mode", "exit_leftward_mode",
+    "exit_micro_mode", "exit_shadow_mode", "exit_subscript_mode", "exit_superscript_mode",
+    "exit_upward_mode", "micro_column_address", "micro_down", "micro_left", "micro_right",
+    "micro_row_address", "micro_up", "order_of_pins", "parm_down_micro", "parm_left_micro",
+    "parm_right_micro", "parm_up_micro", "select_char_set", "set_bottom_margin",
+    "set_bottom_margin_parm", "set_left_margin_parm", "set_right_margin_parm", "set_top_margin",
+    "set_top_margin_parm", "start_bit_image", "start_char_set_def", "stop_bit_image",
+    "stop_char_set_def", "subscript_characters", "superscript_characters", "these_cause_cr",
+    "zero_motion", "char_set_names", "key_mouse", "mouse_info", "req_mouse_pos", "get_mouse",
+    "set_a_foreground", "set_a_background", "pkey_plab", "device_type", "code_set_init",
+    "set0_des_seq", "set1_des_seq", "set2_des_seq", "set3_des_seq", "set_lr_margin",
+    "set_tb_margin", "bit_image_repeat", "bit_image_newline", "bit_image_carriage_return",
+    "color_names", "define_bit_image_region", "end_bit_image_region", "set_color_band",
+    "set_page_length", "display_pc_char", "enter_pc_charset_mode", "exit_pc_charset_mode",
+    "enter_scancode_mode", "exit_scancode_mode", "pc_term_options", "scancode_escape",
+    "alt_scancode_esc", "enter_horizontal_hl_mode", "enter_left_hl_mode", "enter_low_hl_mode",
+    "enter_right_hl_mode", "enter_top_hl_mode", "enter_vertical_hl_mode", "set_a_attributes",
+    "set_pglen_inch", "termcap_init2", "termcap_reset", "linefeed_if_not_lf", "backspace_if_not_bs",
+    "other_non_function_keys", "arrow_key_map", "acs_ulcorner", "acs_llcorner", "acs_urcorner",
+    "acs_lrcorner", "acs_ltee", "acs_rtee", "acs_btee", "acs_ttee", "acs_hline", "acs_vline",
+    "acs_plus", "memory_lock", "memory_unlock", "box_chars_1"];
+
+#[rustfmt::skip]
+pub(crate) static stringnames: &[&str] = &[ "cbt", "_", "cr", "csr", "tbc", "clear",
+    "_", "_", "hpa", "cmdch", "cup", "cud1", "home", "civis", "cub1", "mrcup", "cnorm", "cuf1",
+    "ll", "cuu1", "cvvis", "dch1", "dl1", "dsl", "hd", "smacs", "blink", "bold", "smcup", "smdc",
+    "dim", "smir", "invis", "prot", "rev", "smso", "smul", "ech", "rmacs", "sgr0", "rmcup", "rmdc",
+    "rmir", "rmso", "rmul", "flash", "ff", "fsl", "is1", "is2", "is3", "if", "ich1", "il1", "ip",
+    "kbs", "ktbc", "kclr", "kctab", "_", "_", "kcud1", "_", "_", "_", "_", "_", "_", "_", "_", "_",
+    "_", "_", "_", "_", "_", "khome", "_", "_", "kcub1", "_", "knp", "kpp", "kcuf1", "_", "_",
+    "khts", "_", "rmkx", "smkx", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "rmm", "_",
+    "_", "pad", "dch", "dl", "cud", "ich", "indn", "il", "cub", "cuf", "rin", "cuu", "pfkey",
+    "pfloc", "pfx", "mc0", "mc4", "_", "rep", "rs1", "rs2", "rs3", "rf", "rc", "vpa", "sc", "ind",
+    "ri", "sgr", "_", "wind", "_", "tsl", "uc", "hu", "iprog", "_", "_", "_", "_", "_", "mc5p",
+    "rmp", "acsc", "pln", "kcbt", "smxon", "rmxon", "smam", "rmam", "xonc", "xoffc", "_", "smln",
+    "rmln", "_", "kcan", "kclo", "kcmd", "kcpy", "kcrt", "_", "kent", "kext", "kfnd", "khlp",
+    "kmrk", "kmsg", "kmov", "knxt", "kopn", "kopt", "kprv", "kprt", "krdo", "kref", "krfr", "krpl",
+    "krst", "kres", "ksav", "kspd", "kund", "kBEG", "kCAN", "kCMD", "kCPY", "kCRT", "_", "_",
+    "kslt", "kEND", "kEOL", "kEXT", "kFND", "kHLP", "kHOM", "_", "kLFT", "kMSG", "kMOV", "kNXT",
+    "kOPT", "kPRV", "kPRT", "kRDO", "kRPL", "kRIT", "kRES", "kSAV", "kSPD", "kUND", "rfi", "_", "_",
+    "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_",
+    "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_",
+    "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_",
+    "dclk", "rmclk", "cwin", "wingo", "_", "dial", "qdial", "_", "_", "hook", "pause", "wait", "_",
+    "_", "_", "_", "_", "_", "_", "_", "_", "_", "op", "oc", "initc", "initp", "scp", "setf",
+    "setb", "cpi", "lpi", "chr", "cvr", "defc", "swidm", "sdrfq", "sitm", "slm", "smicm", "snlq",
+    "snrmq", "sshm", "ssubm", "ssupm", "sum", "rwidm", "ritm", "rlm", "rmicm", "rshm", "rsubm",
+    "rsupm", "rum", "mhpa", "mcud1", "mcub1", "mcuf1", "mvpa", "mcuu1", "porder", "mcud", "mcub",
+    "mcuf", "mcuu", "scs", "smgb", "smgbp", "smglp", "smgrp", "smgt", "smgtp", "sbim", "scsd",
+    "rbim", "rcsd", "subcs", "supcs", "docr", "zerom", "csnm", "kmous", "minfo", "reqmp", "getm",
+    "setaf", "setab", "pfxl", "devt", "csin", "s0ds", "s1ds", "s2ds", "s3ds", "smglr", "smgtb",
+    "birep", "binel", "bicr", "colornm", "defbi", "endbi", "setcolor", "slines", "dispc", "smpch",
+    "rmpch", "smsc", "rmsc", "pctrm", "scesc", "scesa", "ehhlm", "elhlm", "elohlm", "erhlm",
+    "ethlm", "evhlm", "sgr1", "slength", "OTi2", "OTrs", "OTnl", "OTbs", "OTko", "OTma", "OTG2",
+    "OTG3", "OTG1", "OTG4", "OTGR", "OTGL", "OTGU", "OTGD", "OTGH", "OTGV", "OTGC", "meml", "memu",
+    "box1"];
+
+fn read_le_u16(r: &mut dyn io::Read) -> io::Result<u16> {
+    let mut b = [0; 2];
+    r.read_exact(&mut b)?;
+    Ok((b[0] as u16) | ((b[1] as u16) << 8))
+}
+
+fn read_le_u32(r: &mut dyn io::Read) -> io::Result<u32> {
+    let mut b = [0; 4];
+    r.read_exact(&mut b)?;
+    Ok((b[0] as u32) | ((b[1] as u32) << 8) | ((b[2] as u32) << 16) | ((b[3] as u32) << 24))
+}
+
+fn read_byte(r: &mut dyn io::Read) -> io::Result<u8> {
+    match r.bytes().next() {
+        Some(s) => s,
+        None => Err(io::Error::new(io::ErrorKind::Other, "end of file")),
+    }
+}
+
+/// Parse a compiled terminfo entry, using long capability names if `longnames`
+/// is true
+pub(crate) fn parse(file: &mut dyn io::Read, longnames: bool) -> Result<TermInfo, String> {
+    macro_rules! t( ($e:expr) => (
+        match $e {
+            Ok(e) => e,
+            Err(e) => return Err(e.to_string())
+        }
+    ) );
+
+    let (bnames, snames, nnames) = if longnames {
+        (boolfnames, stringfnames, numfnames)
+    } else {
+        (boolnames, stringnames, numnames)
+    };
+
+    // Check magic number
+    let magic = t!(read_le_u16(file));
+
+    let extended = match magic {
+        0o0432 => false,
+        0o01036 => true,
+        _ => return Err(format!("invalid magic number, found {:o}", magic)),
+    };
+
+    // According to the spec, these fields must be >= -1 where -1 means that the feature is not
+    // supported. Using 0 instead of -1 works because we skip sections with length 0.
+    macro_rules! read_nonneg {
+        () => {{
+            match t!(read_le_u16(file)) as i16 {
+                n if n >= 0 => n as usize,
+                -1 => 0,
+                _ => return Err("incompatible file: length fields must be  >= -1".to_string()),
+            }
+        }};
+    }
+
+    let names_bytes = read_nonneg!();
+    let bools_bytes = read_nonneg!();
+    let numbers_count = read_nonneg!();
+    let string_offsets_count = read_nonneg!();
+    let string_table_bytes = read_nonneg!();
+
+    if names_bytes == 0 {
+        return Err("incompatible file: names field must be at least 1 byte wide".to_string());
+    }
+
+    if bools_bytes > boolnames.len() {
+        return Err("incompatible file: more booleans than expected".to_string());
+    }
+
+    if numbers_count > numnames.len() {
+        return Err("incompatible file: more numbers than expected".to_string());
+    }
+
+    if string_offsets_count > stringnames.len() {
+        return Err("incompatible file: more string offsets than expected".to_string());
+    }
+
+    // don't read NUL
+    let mut bytes = Vec::new();
+    t!(file.take((names_bytes - 1) as u64).read_to_end(&mut bytes));
+    let names_str = match String::from_utf8(bytes) {
+        Ok(s) => s,
+        Err(_) => return Err("input not utf-8".to_string()),
+    };
+
+    let term_names: Vec<String> = names_str.split('|').map(|s| s.to_string()).collect();
+    // consume NUL
+    if t!(read_byte(file)) != b'\0' {
+        return Err("incompatible file: missing null terminator for names section".to_string());
+    }
+
+    let bools_map: HashMap<String, bool> = t! {
+        (0..bools_bytes).filter_map(|i| match read_byte(file) {
+            Err(e) => Some(Err(e)),
+            Ok(1) => Some(Ok((bnames[i].to_string(), true))),
+            Ok(_) => None
+        }).collect()
+    };
+
+    if (bools_bytes + names_bytes) % 2 == 1 {
+        t!(read_byte(file)); // compensate for padding
+    }
+
+    let numbers_map: HashMap<String, u32> = t! {
+        (0..numbers_count).filter_map(|i| {
+            let number = if extended { read_le_u32(file) } else { read_le_u16(file).map(Into::into) };
+
+            match number {
+                Ok(0xFFFF) => None,
+                Ok(n) => Some(Ok((nnames[i].to_string(), n))),
+                Err(e) => Some(Err(e))
+            }
+        }).collect()
+    };
+
+    let string_map: HashMap<String, Vec<u8>> = if string_offsets_count > 0 {
+        let string_offsets: Vec<u16> =
+            t!((0..string_offsets_count).map(|_| read_le_u16(file)).collect());
+
+        let mut string_table = Vec::new();
+        t!(file.take(string_table_bytes as u64).read_to_end(&mut string_table));
+
+        t!(string_offsets
+            .into_iter()
+            .enumerate()
+            .filter(|&(_, offset)| {
+                // non-entry
+                offset != 0xFFFF
+            })
+            .map(|(i, offset)| {
+                let offset = offset as usize;
+
+                let name = if snames[i] == "_" { stringfnames[i] } else { snames[i] };
+
+                if offset == 0xFFFE {
+                    // undocumented: FFFE indicates cap@, which means the capability is not present
+                    // unsure if the handling for this is correct
+                    return Ok((name.to_string(), Vec::new()));
+                }
+
+                // Find the offset of the NUL we want to go to
+                let nulpos = string_table[offset..string_table_bytes].iter().position(|&b| b == 0);
+                match nulpos {
+                    Some(len) => {
+                        Ok((name.to_string(), string_table[offset..offset + len].to_vec()))
+                    }
+                    None => Err("invalid file: missing NUL in string_table".to_string()),
+                }
+            })
+            .collect())
+    } else {
+        HashMap::new()
+    };
+
+    // And that's all there is to it
+    Ok(TermInfo { names: term_names, bools: bools_map, numbers: numbers_map, strings: string_map })
+}
+
+/// Creates a dummy TermInfo struct for msys terminals
+pub(crate) fn msys_terminfo() -> TermInfo {
+    let mut strings = HashMap::new();
+    strings.insert("sgr0".to_string(), b"\x1B[0m".to_vec());
+    strings.insert("bold".to_string(), b"\x1B[1m".to_vec());
+    strings.insert("setaf".to_string(), b"\x1B[3%p1%dm".to_vec());
+    strings.insert("setab".to_string(), b"\x1B[4%p1%dm".to_vec());
+
+    let mut numbers = HashMap::new();
+    numbers.insert("colors".to_string(), 8);
+
+    TermInfo {
+        names: vec!["cygwin".to_string()], // msys is a fork of an older cygwin version
+        bools: HashMap::new(),
+        numbers,
+        strings,
+    }
+}
diff --git a/library/test/src/term/terminfo/parser/compiled/tests.rs b/library/test/src/term/terminfo/parser/compiled/tests.rs
new file mode 100644 (file)
index 0000000..8a9187b
--- /dev/null
@@ -0,0 +1,8 @@
+use super::*;
+
+#[test]
+fn test_veclens() {
+    assert_eq!(boolfnames.len(), boolnames.len());
+    assert_eq!(numfnames.len(), numnames.len());
+    assert_eq!(stringfnames.len(), stringnames.len());
+}
diff --git a/library/test/src/term/terminfo/searcher.rs b/library/test/src/term/terminfo/searcher.rs
new file mode 100644 (file)
index 0000000..68e181a
--- /dev/null
@@ -0,0 +1,69 @@
+//! ncurses-compatible database discovery.
+//!
+//! Does not support hashed database, only filesystem!
+
+use std::env;
+use std::fs;
+use std::path::PathBuf;
+
+#[cfg(test)]
+mod tests;
+
+/// Return path to database entry for `term`
+#[allow(deprecated)]
+pub(crate) fn get_dbpath_for_term(term: &str) -> Option<PathBuf> {
+    let mut dirs_to_search = Vec::new();
+    let first_char = term.chars().next()?;
+
+    // Find search directory
+    if let Some(dir) = env::var_os("TERMINFO") {
+        dirs_to_search.push(PathBuf::from(dir));
+    }
+
+    if let Ok(dirs) = env::var("TERMINFO_DIRS") {
+        for i in dirs.split(':') {
+            if i == "" {
+                dirs_to_search.push(PathBuf::from("/usr/share/terminfo"));
+            } else {
+                dirs_to_search.push(PathBuf::from(i));
+            }
+        }
+    } else {
+        // Found nothing in TERMINFO_DIRS, use the default paths:
+        // According to  /etc/terminfo/README, after looking at
+        // ~/.terminfo, ncurses will search /etc/terminfo, then
+        // /lib/terminfo, and eventually /usr/share/terminfo.
+        // On Haiku the database can be found at /boot/system/data/terminfo
+        if let Some(mut homedir) = env::home_dir() {
+            homedir.push(".terminfo");
+            dirs_to_search.push(homedir)
+        }
+
+        dirs_to_search.push(PathBuf::from("/etc/terminfo"));
+        dirs_to_search.push(PathBuf::from("/lib/terminfo"));
+        dirs_to_search.push(PathBuf::from("/usr/share/terminfo"));
+        dirs_to_search.push(PathBuf::from("/boot/system/data/terminfo"));
+    }
+
+    // Look for the terminal in all of the search directories
+    for mut p in dirs_to_search {
+        if fs::metadata(&p).is_ok() {
+            p.push(&first_char.to_string());
+            p.push(&term);
+            if fs::metadata(&p).is_ok() {
+                return Some(p);
+            }
+            p.pop();
+            p.pop();
+
+            // on some installations the dir is named after the hex of the char
+            // (e.g., macOS)
+            p.push(&format!("{:x}", first_char as usize));
+            p.push(term);
+            if fs::metadata(&p).is_ok() {
+                return Some(p);
+            }
+        }
+    }
+    None
+}
diff --git a/library/test/src/term/terminfo/searcher/tests.rs b/library/test/src/term/terminfo/searcher/tests.rs
new file mode 100644 (file)
index 0000000..4227a58
--- /dev/null
@@ -0,0 +1,19 @@
+use super::*;
+
+#[test]
+#[ignore = "buildbots don't have ncurses installed and I can't mock everything I need"]
+fn test_get_dbpath_for_term() {
+    // woefully inadequate test coverage
+    // note: current tests won't work with non-standard terminfo hierarchies (e.g., macOS's)
+    use std::env;
+    // FIXME (#9639): This needs to handle non-utf8 paths
+    fn x(t: &str) -> String {
+        let p = get_dbpath_for_term(t).expect("no terminfo entry found");
+        p.to_str().unwrap().to_string()
+    }
+    assert!(x("screen") == "/usr/share/terminfo/s/screen");
+    assert!(get_dbpath_for_term("") == None);
+    env::set_var("TERMINFO_DIRS", ":");
+    assert!(x("screen") == "/usr/share/terminfo/s/screen");
+    env::remove_var("TERMINFO_DIRS");
+}
diff --git a/library/test/src/term/win.rs b/library/test/src/term/win.rs
new file mode 100644 (file)
index 0000000..4bdbd6e
--- /dev/null
@@ -0,0 +1,170 @@
+//! Windows console handling
+
+// FIXME (#13400): this is only a tiny fraction of the Windows console api
+
+use std::io;
+use std::io::prelude::*;
+
+use super::color;
+use super::Terminal;
+
+/// A Terminal implementation that uses the Win32 Console API.
+pub(crate) struct WinConsole<T> {
+    buf: T,
+    def_foreground: color::Color,
+    def_background: color::Color,
+    foreground: color::Color,
+    background: color::Color,
+}
+
+type SHORT = i16;
+type WORD = u16;
+type DWORD = u32;
+type BOOL = i32;
+type HANDLE = *mut u8;
+
+#[allow(non_snake_case)]
+#[repr(C)]
+struct SMALL_RECT {
+    Left: SHORT,
+    Top: SHORT,
+    Right: SHORT,
+    Bottom: SHORT,
+}
+
+#[allow(non_snake_case)]
+#[repr(C)]
+struct COORD {
+    X: SHORT,
+    Y: SHORT,
+}
+
+#[allow(non_snake_case)]
+#[repr(C)]
+struct CONSOLE_SCREEN_BUFFER_INFO {
+    dwSize: COORD,
+    dwCursorPosition: COORD,
+    wAttributes: WORD,
+    srWindow: SMALL_RECT,
+    dwMaximumWindowSize: COORD,
+}
+
+#[allow(non_snake_case)]
+#[link(name = "kernel32")]
+extern "system" {
+    fn SetConsoleTextAttribute(handle: HANDLE, attr: WORD) -> BOOL;
+    fn GetStdHandle(which: DWORD) -> HANDLE;
+    fn GetConsoleScreenBufferInfo(handle: HANDLE, info: *mut CONSOLE_SCREEN_BUFFER_INFO) -> BOOL;
+}
+
+fn color_to_bits(color: color::Color) -> u16 {
+    // magic numbers from mingw-w64's wincon.h
+
+    let bits = match color % 8 {
+        color::BLACK => 0,
+        color::BLUE => 0x1,
+        color::GREEN => 0x2,
+        color::RED => 0x4,
+        color::YELLOW => 0x2 | 0x4,
+        color::MAGENTA => 0x1 | 0x4,
+        color::CYAN => 0x1 | 0x2,
+        color::WHITE => 0x1 | 0x2 | 0x4,
+        _ => unreachable!(),
+    };
+
+    if color >= 8 { bits | 0x8 } else { bits }
+}
+
+fn bits_to_color(bits: u16) -> color::Color {
+    let color = match bits & 0x7 {
+        0 => color::BLACK,
+        0x1 => color::BLUE,
+        0x2 => color::GREEN,
+        0x4 => color::RED,
+        0x6 => color::YELLOW,
+        0x5 => color::MAGENTA,
+        0x3 => color::CYAN,
+        0x7 => color::WHITE,
+        _ => unreachable!(),
+    };
+
+    color | (u32::from(bits) & 0x8) // copy the hi-intensity bit
+}
+
+impl<T: Write + Send + 'static> WinConsole<T> {
+    fn apply(&mut self) {
+        let _unused = self.buf.flush();
+        let mut accum: WORD = 0;
+        accum |= color_to_bits(self.foreground);
+        accum |= color_to_bits(self.background) << 4;
+
+        unsafe {
+            // Magic -11 means stdout, from
+            // https://docs.microsoft.com/en-us/windows/console/getstdhandle
+            //
+            // You may be wondering, "but what about stderr?", and the answer
+            // to that is that setting terminal attributes on the stdout
+            // handle also sets them for stderr, since they go to the same
+            // terminal! Admittedly, this is fragile, since stderr could be
+            // redirected to a different console. This is good enough for
+            // rustc though. See #13400.
+            let out = GetStdHandle(-11i32 as DWORD);
+            SetConsoleTextAttribute(out, accum);
+        }
+    }
+
+    /// Returns `None` whenever the terminal cannot be created for some reason.
+    pub(crate) fn new(out: T) -> io::Result<WinConsole<T>> {
+        use std::mem::MaybeUninit;
+
+        let fg;
+        let bg;
+        unsafe {
+            let mut buffer_info = MaybeUninit::<CONSOLE_SCREEN_BUFFER_INFO>::uninit();
+            if GetConsoleScreenBufferInfo(GetStdHandle(-11i32 as DWORD), buffer_info.as_mut_ptr())
+                != 0
+            {
+                let buffer_info = buffer_info.assume_init();
+                fg = bits_to_color(buffer_info.wAttributes);
+                bg = bits_to_color(buffer_info.wAttributes >> 4);
+            } else {
+                fg = color::WHITE;
+                bg = color::BLACK;
+            }
+        }
+        Ok(WinConsole {
+            buf: out,
+            def_foreground: fg,
+            def_background: bg,
+            foreground: fg,
+            background: bg,
+        })
+    }
+}
+
+impl<T: Write> Write for WinConsole<T> {
+    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
+        self.buf.write(buf)
+    }
+
+    fn flush(&mut self) -> io::Result<()> {
+        self.buf.flush()
+    }
+}
+
+impl<T: Write + Send + 'static> Terminal for WinConsole<T> {
+    fn fg(&mut self, color: color::Color) -> io::Result<bool> {
+        self.foreground = color;
+        self.apply();
+
+        Ok(true)
+    }
+
+    fn reset(&mut self) -> io::Result<bool> {
+        self.foreground = self.def_foreground;
+        self.background = self.def_background;
+        self.apply();
+
+        Ok(true)
+    }
+}
index f9904cb610d2d6e3157abee34161498afd36cabf..d2cf929aa266f82a0b9618b68aa528a92a7de65c 100644 (file)
@@ -580,7 +580,13 @@ class RustBuild(object):
         if ostype != "Linux":
             return
 
-        if not os.path.exists("/etc/NIXOS"):
+        # Use `/etc/os-release` instead of `/etc/NIXOS`.
+        # The latter one does not exist on NixOS when using tmpfs as root.
+        try:
+            with open("/etc/os-release", "r") as f:
+                if not any(line.strip() == "ID=nixos" for line in f):
+                    return
+        except FileNotFoundError:
             return
         if os.path.exists("/lib"):
             return
@@ -989,21 +995,30 @@ class RustBuild(object):
         slow_submodules = self.get_toml('fast-submodules') == "false"
         start_time = time()
         if slow_submodules:
-            print('Unconditionally updating all submodules')
+            print('Unconditionally updating submodules')
         else:
             print('Updating only changed submodules')
         default_encoding = sys.getdefaultencoding()
-        submodules = [s.split(' ', 1)[1] for s in subprocess.check_output(
-            ["git", "config", "--file",
-             os.path.join(self.rust_root, ".gitmodules"),
-             "--get-regexp", "path"]
-        ).decode(default_encoding).splitlines()]
+        # Only update submodules that are needed to build bootstrap.  These are needed because Cargo
+        # currently requires everything in a workspace to be "locally present" when starting a
+        # build, and will give a hard error if any Cargo.toml files are missing.
+        # FIXME: Is there a way to avoid cloning these eagerly? Bootstrap itself doesn't need to
+        #   share a workspace with any tools - maybe it could be excluded from the workspace?
+        #   That will still require cloning the submodules the second you check the standard
+        #   library, though...
+        # FIXME: Is there a way to avoid hard-coding the submodules required?
+        # WARNING: keep this in sync with the submodules hard-coded in bootstrap/lib.rs
+        submodules = [
+            "src/tools/rust-installer",
+            "src/tools/cargo",
+            "src/tools/rls",
+            "src/tools/miri",
+            "library/backtrace",
+            "library/stdarch"
+        ]
         filtered_submodules = []
         submodules_names = []
         for module in submodules:
-            # This is handled by native::Llvm in rustbuild, not here
-            if module.endswith("llvm-project"):
-                continue
             check = self.check_submodule(module, slow_submodules)
             filtered_submodules.append((module, check))
             submodules_names.append(module)
index 5003d6693f72cf77c8175813c381c3df95080d5c..bc106746e57e06e0302fcbcce54988a11c407501 100644 (file)
@@ -7,7 +7,7 @@
 use crate::tool::{prepare_tool_cargo, SourceType};
 use crate::INTERNER;
 use crate::{Compiler, Mode, Subcommand};
-use std::path::PathBuf;
+use std::path::{Path, PathBuf};
 
 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
 pub struct Std {
@@ -72,6 +72,8 @@ fn make_run(run: RunConfig<'_>) {
     }
 
     fn run(self, builder: &Builder<'_>) {
+        builder.update_submodule(&Path::new("library").join("stdarch"));
+
         let target = self.target;
         let compiler = builder.compiler(builder.top_stage, builder.config.build);
 
index 1fae4bee732c01248a5a708e506afb37348f3a89..77d2684b5d2a4870ff1826df2e0a1244eea2eaa1 100644 (file)
@@ -2,7 +2,7 @@
 //! library.
 //!
 //! This module contains some of the real meat in the rustbuild build system
-//! which is where Cargo is used to compiler the standard library, libtest, and
+//! which is where Cargo is used to compile the standard library, libtest, and
 //! compiler. This module is also responsible for assembling the sysroot as it
 //! goes along from the output of the previous stage.
 
@@ -79,6 +79,8 @@ fn run(self, builder: &Builder<'_>) {
             return;
         }
 
+        builder.update_submodule(&Path::new("library").join("stdarch"));
+
         let mut target_deps = builder.ensure(StartupObjects { compiler, target });
 
         let compiler_to_use = builder.compiler_for(compiler.stage, compiler.host, target);
index d3f2c87c0d22f4c966c2215889c60d4b9392be1d..9ec5d4d8ccdb49bcdde2f685177add55aa45642f 100644 (file)
 use crate::tool::{self, prepare_tool_cargo, SourceType, Tool};
 use crate::util::symlink_dir;
 
+macro_rules! submodule_helper {
+    ($path:expr, submodule) => {
+        $path
+    };
+    ($path:expr, submodule = $submodule:literal) => {
+        $submodule
+    };
+}
+
 macro_rules! book {
-    ($($name:ident, $path:expr, $book_name:expr;)+) => {
+    ($($name:ident, $path:expr, $book_name:expr $(, submodule $(= $submodule:literal)? )? ;)+) => {
         $(
             #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
         pub struct $name {
@@ -46,6 +55,10 @@ fn make_run(run: RunConfig<'_>) {
             }
 
             fn run(self, builder: &Builder<'_>) {
+                $(
+                    let path = Path::new(submodule_helper!( $path, submodule $( = $submodule )? ));
+                    builder.update_submodule(&path);
+                )?
                 builder.ensure(RustbookSrc {
                     target: self.target,
                     name: INTERNER.intern_str($book_name),
@@ -59,13 +72,16 @@ fn run(self, builder: &Builder<'_>) {
 
 // NOTE: When adding a book here, make sure to ALSO build the book by
 // adding a build step in `src/bootstrap/builder.rs`!
+// NOTE: Make sure to add the corresponding submodule when adding a new book.
+// FIXME: Make checking for a submodule automatic somehow (maybe by having a list of all submodules
+// and checking against it?).
 book!(
-    CargoBook, "src/tools/cargo/src/doc", "cargo";
-    EditionGuide, "src/doc/edition-guide", "edition-guide";
-    EmbeddedBook, "src/doc/embedded-book", "embedded-book";
-    Nomicon, "src/doc/nomicon", "nomicon";
-    Reference, "src/doc/reference", "reference";
-    RustByExample, "src/doc/rust-by-example", "rust-by-example";
+    CargoBook, "src/tools/cargo/src/doc", "cargo", submodule = "src/tools/cargo";
+    EditionGuide, "src/doc/edition-guide", "edition-guide", submodule;
+    EmbeddedBook, "src/doc/embedded-book", "embedded-book", submodule;
+    Nomicon, "src/doc/nomicon", "nomicon", submodule;
+    Reference, "src/doc/reference", "reference", submodule;
+    RustByExample, "src/doc/rust-by-example", "rust-by-example", submodule;
     RustdocBook, "src/doc/rustdoc", "rustdoc";
 );
 
@@ -197,6 +213,9 @@ fn make_run(run: RunConfig<'_>) {
     /// * Index page
     /// * Redirect pages
     fn run(self, builder: &Builder<'_>) {
+        let relative_path = Path::new("src").join("doc").join("book");
+        builder.update_submodule(&relative_path);
+
         let compiler = self.compiler;
         let target = self.target;
 
@@ -204,7 +223,7 @@ fn run(self, builder: &Builder<'_>) {
         builder.ensure(RustbookSrc {
             target,
             name: INTERNER.intern_str("book"),
-            src: INTERNER.intern_path(builder.src.join("src/doc/book")),
+            src: INTERNER.intern_path(builder.src.join(&relative_path)),
         });
 
         // building older edition redirects
@@ -212,7 +231,7 @@ fn run(self, builder: &Builder<'_>) {
             builder.ensure(RustbookSrc {
                 target,
                 name: INTERNER.intern_string(format!("book/{}", edition)),
-                src: INTERNER.intern_path(builder.src.join("src/doc/book").join(edition)),
+                src: INTERNER.intern_path(builder.src.join(&relative_path).join(edition)),
             });
         }
 
@@ -221,7 +240,7 @@ fn run(self, builder: &Builder<'_>) {
 
         // build the redirect pages
         builder.info(&format!("Documenting book redirect pages ({})", target));
-        for file in t!(fs::read_dir(builder.src.join("src/doc/book/redirects"))) {
+        for file in t!(fs::read_dir(builder.src.join(&relative_path).join("redirects"))) {
             let file = t!(file);
             let path = file.path();
             let path = path.to_str().unwrap();
index 69c5de0b408316317754aea97c2345e4ef782442..6bcdbe3e4bbbb33a5faeffb0e4855c8367a04589 100644 (file)
@@ -477,17 +477,120 @@ pub fn build_triple(&self) -> &[Interned<String>] {
         slice::from_ref(&self.build.triple)
     }
 
+    // modified from `check_submodule` and `update_submodule` in bootstrap.py
+    /// Given a path to the directory of a submodule, update it.
+    ///
+    /// `relative_path` should be relative to the root of the git repository, not an absolute path.
+    pub(crate) fn update_submodule(&self, relative_path: &Path) {
+        fn dir_is_empty(dir: &Path) -> bool {
+            t!(std::fs::read_dir(dir)).next().is_none()
+        }
+
+        if !self.config.submodules {
+            return;
+        }
+
+        let absolute_path = self.config.src.join(relative_path);
+
+        // NOTE: The check for the empty directory is here because when running x.py the first time,
+        // the submodule won't be checked out. Check it out now so we can build it.
+        if !channel::GitInfo::new(false, relative_path).is_git() && !dir_is_empty(&absolute_path) {
+            return;
+        }
+
+        // check_submodule
+        if self.config.fast_submodules {
+            let checked_out_hash = output(
+                Command::new("git").args(&["rev-parse", "HEAD"]).current_dir(&absolute_path),
+            );
+            // update_submodules
+            let recorded = output(
+                Command::new("git")
+                    .args(&["ls-tree", "HEAD"])
+                    .arg(relative_path)
+                    .current_dir(&self.config.src),
+            );
+            let actual_hash = recorded
+                .split_whitespace()
+                .nth(2)
+                .unwrap_or_else(|| panic!("unexpected output `{}`", recorded));
+
+            // update_submodule
+            if actual_hash == checked_out_hash.trim_end() {
+                // already checked out
+                return;
+            }
+        }
+
+        println!("Updating submodule {}", relative_path.display());
+        self.run(
+            Command::new("git")
+                .args(&["submodule", "-q", "sync"])
+                .arg(relative_path)
+                .current_dir(&self.config.src),
+        );
+
+        // Try passing `--progress` to start, then run git again without if that fails.
+        let update = |progress: bool| {
+            let mut git = Command::new("git");
+            git.args(&["submodule", "update", "--init", "--recursive"]);
+            if progress {
+                git.arg("--progress");
+            }
+            git.arg(relative_path).current_dir(&self.config.src);
+            git
+        };
+        // NOTE: doesn't use `try_run` because this shouldn't print an error if it fails.
+        if !update(true).status().map_or(false, |status| status.success()) {
+            self.run(&mut update(false));
+        }
+
+        self.run(Command::new("git").args(&["reset", "-q", "--hard"]).current_dir(&absolute_path));
+        self.run(Command::new("git").args(&["clean", "-qdfx"]).current_dir(absolute_path));
+    }
+
+    /// If any submodule has been initialized already, sync it unconditionally.
+    /// This avoids contributors checking in a submodule change by accident.
+    pub fn maybe_update_submodules(&self) {
+        // WARNING: keep this in sync with the submodules hard-coded in bootstrap.py
+        const BOOTSTRAP_SUBMODULES: &[&str] = &[
+            "src/tools/rust-installer",
+            "src/tools/cargo",
+            "src/tools/rls",
+            "src/tools/miri",
+            "library/backtrace",
+            "library/stdarch",
+        ];
+        // Avoid running git when there isn't a git checkout.
+        if !self.config.submodules {
+            return;
+        }
+        let output = output(
+            Command::new("git")
+                .args(&["config", "--file"])
+                .arg(&self.config.src.join(".gitmodules"))
+                .args(&["--get-regexp", "path"]),
+        );
+        for line in output.lines() {
+            // Look for `submodule.$name.path = $path`
+            // Sample output: `submodule.src/rust-installer.path src/tools/rust-installer`
+            let submodule = Path::new(line.splitn(2, ' ').nth(1).unwrap());
+            // avoid updating submodules twice
+            if !BOOTSTRAP_SUBMODULES.iter().any(|&p| Path::new(p) == submodule)
+                && channel::GitInfo::new(false, submodule).is_git()
+            {
+                self.update_submodule(submodule);
+            }
+        }
+    }
+
     /// Executes the entire build, as configured by the flags and configuration.
     pub fn build(&mut self) {
         unsafe {
             job::setup(self);
         }
 
-        // If the LLVM submodule has been initialized already, sync it unconditionally. This avoids
-        // contributors checking in a submodule change by accident.
-        if self.in_tree_llvm_info.is_git() {
-            native::update_llvm_submodule(self);
-        }
+        self.maybe_update_submodules();
 
         if let Subcommand::Format { check, paths } = &self.config.cmd {
             return format::format(self, *check, &paths);
index 0be42d9b2348623abf72d4c256df3a4966d8a4fb..1be414b29a1aec2ebf195cdd4055e11f56b1ee39 100644 (file)
@@ -21,7 +21,7 @@
 use crate::builder::{Builder, RunConfig, ShouldRun, Step};
 use crate::config::TargetSelection;
 use crate::util::{self, exe};
-use crate::{Build, GitRepo};
+use crate::GitRepo;
 use build_helper::up_to_date;
 
 pub struct Meta {
@@ -91,86 +91,6 @@ pub fn prebuilt_llvm_config(
     Err(Meta { stamp, build_llvm_config, out_dir, root: root.into() })
 }
 
-// modified from `check_submodule` and `update_submodule` in bootstrap.py
-pub(crate) fn update_llvm_submodule(build: &Build) {
-    let llvm_project = &Path::new("src").join("llvm-project");
-
-    fn dir_is_empty(dir: &Path) -> bool {
-        t!(std::fs::read_dir(dir)).next().is_none()
-    }
-
-    if !build.config.submodules {
-        return;
-    }
-
-    // NOTE: The check for the empty directory is here because when running x.py
-    // the first time, the llvm submodule won't be checked out. Check it out
-    // now so we can build it.
-    if !build.in_tree_llvm_info.is_git() && !dir_is_empty(&build.config.src.join(llvm_project)) {
-        return;
-    }
-
-    // check_submodule
-    if build.config.fast_submodules {
-        let checked_out_hash = output(
-            Command::new("git")
-                .args(&["rev-parse", "HEAD"])
-                .current_dir(build.config.src.join(llvm_project)),
-        );
-        // update_submodules
-        let recorded = output(
-            Command::new("git")
-                .args(&["ls-tree", "HEAD"])
-                .arg(llvm_project)
-                .current_dir(&build.config.src),
-        );
-        let actual_hash = recorded
-            .split_whitespace()
-            .nth(2)
-            .unwrap_or_else(|| panic!("unexpected output `{}`", recorded));
-
-        // update_submodule
-        if actual_hash == checked_out_hash.trim_end() {
-            // already checked out
-            return;
-        }
-    }
-
-    println!("Updating submodule {}", llvm_project.display());
-    build.run(
-        Command::new("git")
-            .args(&["submodule", "-q", "sync"])
-            .arg(llvm_project)
-            .current_dir(&build.config.src),
-    );
-
-    // Try passing `--progress` to start, then run git again without if that fails.
-    let update = |progress: bool| {
-        let mut git = Command::new("git");
-        git.args(&["submodule", "update", "--init", "--recursive"]);
-        if progress {
-            git.arg("--progress");
-        }
-        git.arg(llvm_project).current_dir(&build.config.src);
-        git
-    };
-    // NOTE: doesn't use `try_run` because this shouldn't print an error if it fails.
-    if !update(true).status().map_or(false, |status| status.success()) {
-        build.run(&mut update(false));
-    }
-
-    build.run(
-        Command::new("git")
-            .args(&["reset", "-q", "--hard"])
-            .current_dir(build.config.src.join(llvm_project)),
-    );
-    build.run(
-        Command::new("git")
-            .args(&["clean", "-qdfx"])
-            .current_dir(build.config.src.join(llvm_project)),
-    );
-}
-
 #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
 pub struct Llvm {
     pub target: TargetSelection,
@@ -208,9 +128,7 @@ fn run(self, builder: &Builder<'_>) -> PathBuf {
                 Err(m) => m,
             };
 
-        if !builder.config.dry_run {
-            update_llvm_submodule(builder);
-        }
+        builder.update_submodule(&Path::new("src").join("llvm-project"));
         if builder.config.llvm_link_shared
             && (target.contains("windows") || target.contains("apple-darwin"))
         {
index 61ffae47e2ad02a24bc1d2d8afade03f34e1509c..31f18d81c7c0fb403892b9eebdde35e19699e406 100644 (file)
@@ -907,18 +907,27 @@ fn run(self, builder: &Builder<'_>) {
         // We remove existing folder to be sure there won't be artifacts remaining.
         let _ = fs::remove_dir_all(&out_dir);
 
-        let src_path = "src/test/rustdoc-gui/src";
+        let src_path = builder.build.src.join("src/test/rustdoc-gui/src");
         // We generate docs for the libraries present in the rustdoc-gui's src folder.
-        let mut cargo = Command::new(&builder.initial_cargo);
-        cargo
-            .arg("doc")
-            .arg("--workspace")
-            .arg("--target-dir")
-            .arg(&out_dir)
-            .env("RUSTDOC", builder.rustdoc(self.compiler))
-            .env("RUSTC", builder.rustc(self.compiler))
-            .current_dir(&builder.build.src.join(src_path));
-        builder.run(&mut cargo);
+        for entry in src_path.read_dir().expect("read_dir call failed") {
+            if let Ok(entry) = entry {
+                let path = entry.path();
+
+                if !path.is_dir() {
+                    continue;
+                }
+
+                let mut cargo = Command::new(&builder.initial_cargo);
+                cargo
+                    .arg("doc")
+                    .arg("--target-dir")
+                    .arg(&out_dir)
+                    .env("RUSTDOC", builder.rustdoc(self.compiler))
+                    .env("RUSTC", builder.rustc(self.compiler))
+                    .current_dir(path);
+                builder.run(&mut cargo);
+            }
+        }
 
         // We now run GUI tests.
         let mut command = Command::new(&nodejs);
@@ -1833,7 +1842,10 @@ fn make_run(run: RunConfig<'_>) {
     }
 
     fn run(self, builder: &Builder<'_>) {
-        let src = builder.src.join("src/doc/rustc-dev-guide");
+        let relative_path = Path::new("src").join("doc").join("rustc-dev-guide");
+        builder.update_submodule(&relative_path);
+
+        let src = builder.src.join(relative_path);
         let mut rustbook_cmd = builder.tool_cmd(Tool::Rustbook);
         let toolstate = if try_run(builder, rustbook_cmd.arg("linkcheck").arg(&src)) {
             ToolState::TestPass
index aa7fe658df3209cdeb3b7050d1dc0e1d29aff4f3..f5e3f61dcc88f6fb5827382bd8dcef13780dc8b2 100644 (file)
@@ -1,7 +1,7 @@
 use std::collections::HashSet;
 use std::env;
 use std::fs;
-use std::path::PathBuf;
+use std::path::{Path, PathBuf};
 use std::process::{exit, Command};
 
 use build_helper::t;
@@ -670,7 +670,8 @@ macro_rules! tool_extended {
        $path:expr,
        $tool_name:expr,
        stable = $stable:expr,
-       $(in_tree = $in_tree:expr,)*
+       $(in_tree = $in_tree:expr,)?
+       $(submodule = $submodule:literal,)?
        $extra_deps:block;)+) => {
         $(
             #[derive(Debug, Clone, Hash, PartialEq, Eq)]
@@ -714,6 +715,7 @@ fn make_run(run: RunConfig<'_>) {
             #[allow(unused_mut)]
             fn run(mut $sel, $builder: &Builder<'_>) -> Option<PathBuf> {
                 $extra_deps
+                $( $builder.update_submodule(&Path::new("src").join("tools").join($submodule)); )?
                 $builder.ensure(ToolBuild {
                     compiler: $sel.compiler,
                     target: $sel.target,
@@ -736,6 +738,8 @@ fn run(mut $sel, $builder: &Builder<'_>) -> Option<PathBuf> {
 
 // Note: tools need to be also added to `Builder::get_step_descriptions` in `builder.rs`
 // to make `./x.py build <tool>` work.
+// Note: Most submodule updates for tools are handled by bootstrap.py, since they're needed just to
+// invoke Cargo to build bootstrap. See the comment there for more details.
 tool_extended!((self, builder),
     Cargofmt, rustfmt, "src/tools/rustfmt", "cargo-fmt", stable=true, in_tree=true, {};
     CargoClippy, clippy, "src/tools/clippy", "cargo-clippy", stable=true, in_tree=true, {};
@@ -752,7 +756,7 @@ fn run(mut $sel, $builder: &Builder<'_>) -> Option<PathBuf> {
     };
     RustDemangler, rust_demangler, "src/tools/rust-demangler", "rust-demangler", stable=false, in_tree=true, {};
     Rustfmt, rustfmt, "src/tools/rustfmt", "rustfmt", stable=true, in_tree=true, {};
-    RustAnalyzer, rust_analyzer, "src/tools/rust-analyzer/crates/rust-analyzer", "rust-analyzer", stable=false, {};
+    RustAnalyzer, rust_analyzer, "src/tools/rust-analyzer/crates/rust-analyzer", "rust-analyzer", stable=false, submodule="rust-analyzer", {};
 );
 
 impl<'a> Builder<'a> {
index a90f07f1e9a7fc75dc9105a6c6f16d5c13edceb0..eac55314210519238652f12b30fec9daea61f7fe 160000 (submodule)
@@ -1 +1 @@
-Subproject commit a90f07f1e9a7fc75dc9105a6c6f16d5c13edceb0
+Subproject commit eac55314210519238652f12b30fec9daea61f7fe
index 5d57b3832f8d308a9f478ce0a69799548f27ad4d..af696ce8ea526445590ae0ca66a8128d2a95a69a 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 5d57b3832f8d308a9f478ce0a69799548f27ad4d
+Subproject commit af696ce8ea526445590ae0ca66a8128d2a95a69a
index 506840eb73b0749336e1d5274e16d6393892ee82..09986cd352404eb4659db44613b27cac9aa652fc 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 506840eb73b0749336e1d5274e16d6393892ee82
+Subproject commit 09986cd352404eb4659db44613b27cac9aa652fc
index ab60513a3a5a0591e237fddff5d027a982648392..82d75cf423e4a7824fb36e73ccb18519d6900610 160000 (submodule)
@@ -1 +1 @@
-Subproject commit ab60513a3a5a0591e237fddff5d027a982648392
+Subproject commit 82d75cf423e4a7824fb36e73ccb18519d6900610
index 028f93a61500fe8f746ee7cc6b204ea6c9f42935..1db6bb483cc87ad3b424d9aba764fe622960a1be 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 028f93a61500fe8f746ee7cc6b204ea6c9f42935
+Subproject commit 1db6bb483cc87ad3b424d9aba764fe622960a1be
index 60e282559104035985331645907c3d9f842312c5..93422c21baca585dc88357ec886a48f6ddc7d665 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 60e282559104035985331645907c3d9f842312c5
+Subproject commit 93422c21baca585dc88357ec886a48f6ddc7d665
diff --git a/src/doc/unstable-book/src/compiler-flags/force-warn.md b/src/doc/unstable-book/src/compiler-flags/force-warn.md
new file mode 100644 (file)
index 0000000..052de0f
--- /dev/null
@@ -0,0 +1,21 @@
+# `force-warn`
+
+The tracking issue for this feature is: [#85512](https://github.com/rust-lang/rust/issues/85512).
+
+------------------------
+
+This feature allows you to cause any lint to produce a warning even if the lint has a different level by default or another level is set somewhere else. For instance, the `force-warn` option can be used to make a lint (e.g., `dead_code`) produce a warning even if that lint is allowed in code with `#![allow(dead_code)]`.
+
+## Example
+
+```rust,ignore (partial-example)
+#![allow(dead_code)]
+
+fn dead_function() {}
+// This would normally not produce a warning even though the
+// function is not used, because dead code is being allowed
+
+fn main() {}
+```
+
+We can force a warning to be produced by providing `--force-warn dead_code` to rustc.
diff --git a/src/doc/unstable-book/src/compiler-flags/force-warns.md b/src/doc/unstable-book/src/compiler-flags/force-warns.md
deleted file mode 100644 (file)
index 0a205be..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-# `force-warns`
-
-The tracking issue for this feature is: [#85512](https://github.com/rust-lang/rust/issues/85512).
-
-------------------------
-
-This feature allows you to cause any lint to produce a warning even if the lint has a different level by default or another level is set somewhere else. For instance, the `force-warns` option can be used to make a lint (e.g., `dead_code`) produce a warning even if that lint is allowed in code with `#![allow(dead_code)]`.
-
-## Example
-
-```rust,ignore (partial-example)
-#![allow(dead_code)]
-
-fn dead_function() {}
-// This would normally not produce a warning even though the
-// function is not used, because dead code is being allowed
-
-fn main() {}
-```
-
-We can force a warning to be produced by providing `--force-warns dead_code` to rustc.
diff --git a/src/doc/unstable-book/src/language-features/impl-trait-in-bindings.md b/src/doc/unstable-book/src/language-features/impl-trait-in-bindings.md
deleted file mode 100644 (file)
index 5c6aa91..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-# `impl_trait_in_bindings`
-
-The tracking issue for this feature is: [#63065]
-
-[#63065]: https://github.com/rust-lang/rust/issues/63065
-
-------------------------
-
-The `impl_trait_in_bindings` feature gate lets you use `impl Trait` syntax in
-`let`, `static`, and `const` bindings.
-
-A simple example is:
-
-```rust
-#![feature(impl_trait_in_bindings)]
-
-use std::fmt::Debug;
-
-fn main() {
-    let a: impl Debug + Clone = 42;
-    let b = a.clone();
-    println!("{:?}", b); // prints `42`
-}
-```
-
-Note however that because the types of `a` and `b` are opaque in the above
-example, calling inherent methods or methods outside of the specified traits
-(e.g., `a.abs()` or `b.abs()`) is not allowed, and yields an error.
index adbdde0d92cd6034fe7ea78c33dc7dec546757c2..abd1fd2bf39a29c13702beaf484680ae232f53f8 100644 (file)
@@ -459,7 +459,31 @@ fn println_condition(condition: Condition) {
                 })
                 .collect(),
         ];
-        let default_settings = default_settings.into_iter().flatten().collect();
+        let default_settings = default_settings
+            .into_iter()
+            .flatten()
+            .map(
+                // The keys here become part of `data-` attribute names in the generated HTML.  The
+                // browser does a strange mapping when converting them into attributes on the
+                // `dataset` property on the DOM HTML Node:
+                //   https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/dataset
+                //
+                // The original key values we have are the same as the DOM storage API keys and the
+                // command line options, so contain `-`.  Our Javascript needs to be able to look
+                // these values up both in `dataset` and in the storage API, so it needs to be able
+                // to convert the names back and forth.  Despite doing this kebab-case to
+                // StudlyCaps transformation automatically, the JS DOM API does not provide a
+                // mechanism for doing the just transformation on a string.  So we want to avoid
+                // the StudlyCaps representation in the `dataset` property.
+                //
+                // We solve this by replacing all the `-`s with `_`s.  We do that here, when we
+                // generate the `data-` attributes, and in the JS, when we look them up.  (See
+                // `getSettingValue` in `storage.js.`) Converting `-` to `_` is simple in JS.
+                //
+                // The values will be HTML-escaped by the default Tera escaping.
+                |(k, v)| (k.replace('-', "_"), v),
+            )
+            .collect();
 
         let test_args = matches.opt_strs("test-args");
         let test_args: Vec<String> =
@@ -632,7 +656,7 @@ fn println_condition(condition: Condition) {
         let show_type_layout = matches.opt_present("show-type-layout");
         let nocapture = matches.opt_present("nocapture");
 
-        let (lint_opts, describe_lints, lint_cap, _) =
+        let (lint_opts, describe_lints, lint_cap) =
             get_cmd_lint_options(matches, error_format, &debugging_opts);
 
         Ok(Options {
index e21469dc9c343e84d17f295b3bc9588356cb8a83..908e292d968efbb045a2bb474a540a1e1e0cc06d 100644 (file)
@@ -57,7 +57,7 @@ pub(crate) fn opts() -> Options {
 
 /// A subset of [`opts()`] used for rendering summaries.
 pub(crate) fn summary_opts() -> Options {
-    Options::ENABLE_STRIKETHROUGH | Options::ENABLE_SMART_PUNCTUATION
+    Options::ENABLE_STRIKETHROUGH | Options::ENABLE_SMART_PUNCTUATION | Options::ENABLE_TABLES
 }
 
 /// When `to_string` is called, this struct will emit the HTML corresponding to
@@ -522,6 +522,10 @@ fn check_if_allowed_tag(t: &Tag<'_>) -> bool {
     )
 }
 
+fn is_forbidden_tag(t: &Tag<'_>) -> bool {
+    matches!(t, Tag::CodeBlock(_) | Tag::Table(_) | Tag::TableHead | Tag::TableRow | Tag::TableCell)
+}
+
 impl<'a, I: Iterator<Item = Event<'a>>> Iterator for SummaryLine<'a, I> {
     type Item = Event<'a>;
 
@@ -535,14 +539,17 @@ fn next(&mut self) -> Option<Self::Item> {
         if let Some(event) = self.inner.next() {
             let mut is_start = true;
             let is_allowed_tag = match event {
-                Event::Start(Tag::CodeBlock(_)) | Event::End(Tag::CodeBlock(_)) => {
-                    return None;
-                }
                 Event::Start(ref c) => {
+                    if is_forbidden_tag(c) {
+                        return None;
+                    }
                     self.depth += 1;
                     check_if_allowed_tag(c)
                 }
                 Event::End(ref c) => {
+                    if is_forbidden_tag(c) {
+                        return None;
+                    }
                     self.depth -= 1;
                     is_start = false;
                     check_if_allowed_tag(c)
index f7073a8751fa18723622c06d15c6e26a29adae86..552958d5e402b8b61c78de2a8cd8ca9035a9a9c1 100644 (file)
@@ -1,6 +1,7 @@
 use clean::AttributesExt;
 
 use std::cmp::Ordering;
+use std::fmt;
 
 use rustc_data_structures::fx::FxHashMap;
 use rustc_hir as hir;
@@ -155,7 +156,7 @@ fn should_hide_fields(n_fields: usize) -> bool {
     n_fields > 12
 }
 
-fn toggle_open(w: &mut Buffer, text: &str) {
+fn toggle_open(w: &mut Buffer, text: impl fmt::Display) {
     write!(
         w,
         "<details class=\"rustdoc-toggle type-contents-toggle\">\
@@ -481,6 +482,9 @@ fn item_trait(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Tra
     let consts = t.items.iter().filter(|m| m.is_associated_const()).collect::<Vec<_>>();
     let required = t.items.iter().filter(|m| m.is_ty_method()).collect::<Vec<_>>();
     let provided = t.items.iter().filter(|m| m.is_method()).collect::<Vec<_>>();
+    let count_types = types.len();
+    let count_consts = consts.len();
+    let count_methods = required.len() + provided.len();
 
     // Output the trait definition
     wrap_into_docblock(w, |w| {
@@ -511,9 +515,12 @@ fn item_trait(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Tra
             let mut toggle = false;
 
             // If there are too many associated types, hide _everything_
-            if should_hide_fields(types.len()) {
+            if should_hide_fields(count_types) {
                 toggle = true;
-                toggle_open(w, "associated items");
+                toggle_open(
+                    w,
+                    format_args!("{} associated items", count_types + count_consts + count_methods),
+                );
             }
             for t in &types {
                 render_assoc_item(w, t, AssocItemLink::Anchor(None), ItemType::Trait, cx);
@@ -523,9 +530,18 @@ fn item_trait(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Tra
             // We also do this if the types + consts is large because otherwise we could
             // render a bunch of types and _then_ a bunch of consts just because both were
             // _just_ under the limit
-            if !toggle && should_hide_fields(types.len() + consts.len()) {
+            if !toggle && should_hide_fields(count_types + count_consts) {
                 toggle = true;
-                toggle_open(w, "associated constants and methods");
+                toggle_open(
+                    w,
+                    format_args!(
+                        "{} associated constant{} and {} method{}",
+                        count_consts,
+                        pluralize(count_consts),
+                        count_methods,
+                        pluralize(count_methods),
+                    ),
+                );
             }
             if !types.is_empty() && !consts.is_empty() {
                 w.write_str("\n");
@@ -534,9 +550,9 @@ fn item_trait(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Tra
                 render_assoc_item(w, t, AssocItemLink::Anchor(None), ItemType::Trait, cx);
                 w.write_str(";\n");
             }
-            if !toggle && should_hide_fields(required.len() + provided.len()) {
+            if !toggle && should_hide_fields(count_methods) {
                 toggle = true;
-                toggle_open(w, "methods");
+                toggle_open(w, format_args!("{} methods", count_methods));
             }
             if !consts.is_empty() && !required.is_empty() {
                 w.write_str("\n");
@@ -933,9 +949,10 @@ fn item_enum(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, e: &clean::Enum
             w.write_str(" {}");
         } else {
             w.write_str(" {\n");
-            let toggle = should_hide_fields(e.variants.len());
+            let count_variants = e.variants.len();
+            let toggle = should_hide_fields(count_variants);
             if toggle {
-                toggle_open(w, "variants");
+                toggle_open(w, format_args!("{} variants", count_variants));
             }
             for v in &e.variants {
                 w.write_str("    ");
@@ -1012,7 +1029,8 @@ fn item_enum(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, e: &clean::Enum
 
             use crate::clean::Variant;
             if let clean::VariantItem(Variant::Struct(ref s)) = *variant.kind {
-                toggle_open(w, "fields");
+                let count_fields = s.fields.len();
+                toggle_open(w, format_args!("{} field{}", count_fields, pluralize(count_fields)));
                 let variant_id = cx.derive_id(format!(
                     "{}.{}.fields",
                     ItemType::Variant,
@@ -1385,7 +1403,7 @@ fn render_union(
         fields.iter().filter(|f| matches!(*f.kind, clean::StructFieldItem(..))).count();
     let toggle = should_hide_fields(count_fields);
     if toggle {
-        toggle_open(w, "fields");
+        toggle_open(w, format_args!("{} fields", count_fields));
     }
 
     for field in fields {
@@ -1441,7 +1459,7 @@ fn render_struct(
             let has_visible_fields = count_fields > 0;
             let toggle = should_hide_fields(count_fields);
             if toggle {
-                toggle_open(w, "fields");
+                toggle_open(w, format_args!("{} fields", count_fields));
             }
             for field in fields {
                 if let clean::StructFieldItem(ref ty) = *field.kind {
@@ -1618,3 +1636,7 @@ fn document_type_layout(w: &mut Buffer, cx: &Context<'_>, ty_def_id: DefId) {
 
     writeln!(w, "</div>");
 }
+
+fn pluralize(count: usize) -> &'static str {
+    if count > 1 { "s" } else { "" }
+}
index e608ad05b17dac04606b1f3e91343c59dfe0371d..6672093eb7bc60cc83ce13eb0d450474125724f0 100644 (file)
@@ -560,7 +560,8 @@ nav.sub {
 .docblock table {
        margin: .5em 0;
        width: calc(100% - 2px);
-       border: 1px dashed;
+       overflow-x: auto;
+       display: block;
 }
 
 .docblock table td {
index 8296c3f91ca3b1afc7f03696150d54570852b564..354cdd2fb035b2d9e9d7e471b0ce551fa5c13aa9 100644 (file)
@@ -140,7 +140,7 @@ pre, .rustdoc.source .example-wrap {
        border-bottom-color: #5c6773;
 }
 
-.docblock table, .docblock table td, .docblock table th {
+.docblock table td, .docblock table th {
        border-color: #5c6773;
 }
 
index 599fb942dbe2a35c420e38d2939542c06718b581..b4f5a13c815095282834bf8cca2b5bc394d1e673 100644 (file)
@@ -97,7 +97,7 @@ pre, .rustdoc.source .example-wrap {
        border-bottom-color: #DDD;
 }
 
-.docblock table, .docblock table td, .docblock table th {
+.docblock table td, .docblock table th {
        border-color: #ddd;
 }
 
index 0c2799727f3e30d71243807c12ebfd40f9b3a92c..29cbcd65ce81de54800ed4ecadf9de47cf67fc83 100644 (file)
@@ -97,7 +97,7 @@ pre, .rustdoc.source .example-wrap {
        border-bottom-color: #ddd;
 }
 
-.docblock table, .docblock table td, .docblock table th {
+.docblock table td, .docblock table th {
        border-color: #ddd;
 }
 
index 2eaa81a97d8c5e46f59d1441a4f0bae37eed007e..78ed17e6899e9aa17c0d526b7f93ba64cf3d51a2 100644 (file)
@@ -22,6 +22,8 @@ function getSettingValue(settingName) {
         return current;
     }
     if (settingsDataset !== null) {
+        // See the comment for `default_settings.into_iter()` etc. in
+        // `Options::from_matches` in `librustdoc/config.rs`.
         var def = settingsDataset[settingName.replace(/-/g,'_')];
         if (def !== undefined) {
             return def;
index 19deaa11388d8601d012b03a6299d3ba44939506..fa755777584f3cdacb58abe4cc4aa6722ce4d7e9 100644 (file)
@@ -511,10 +511,10 @@ fn opts() -> Vec<RustcOptGroup> {
                 "LEVEL",
             )
         }),
-        unstable("force-warns", |o| {
+        unstable("force-warn", |o| {
             o.optopt(
                 "",
-                "force-warns",
+                "force-warn",
                 "Lints that will warn even if allowed somewhere else",
                 "LINTS",
             )
index 20a49f0bd26ebc1344b29d7238f6388feee66548..28ab176ba509acd2a70ec88ea483f86915ba59fb 100644 (file)
 // cdb-command:x a!function_names::*::impl_function*
 // cdb-check:[...] a!function_names::Mod1::TestStruct2::impl_function (void)
 // cdb-check:[...] a!function_names::TestStruct1::impl_function (void)
-// cdb-check:[...] a!function_names::GenericStruct<i32, i32>::impl_function<i32, i32> (void)
+// cdb-check:[...] a!function_names::GenericStruct<i32,i32>::impl_function<i32,i32> (void)
 
 // Trait implementations
 // cdb-command:x a!function_names::*::trait_function*
 // cdb-check:[...] a!function_names::impl$3::trait_function<i32> (void)
+// cdb-check:[...] a!function_names::impl$6::trait_function<i32,1> (void)
 // cdb-check:[...] a!function_names::impl$1::trait_function (void)
-// cdb-check:[...] a!function_names::impl$6::trait_function<i32, 1> (void)
 // cdb-check:[...] a!function_names::impl$5::trait_function3<function_names::TestStruct1> (void)
 // cdb-check:[...] a!function_names::Mod1::impl$1::trait_function (void)
 
 // Closure
 // cdb-command:x a!function_names::*::closure*
+// cdb-check:[...] a!function_names::impl$2::impl_function::closure$0<i32,i32> (void)
 // cdb-check:[...] a!function_names::main::closure$0 (void)
 // cdb-check:[...] a!function_names::generic_func::closure$0<i32> (void)
-// cdb-check:[...] a!function_names::impl$2::impl_function::closure$0<i32, i32> (void)
 
 // Generator
 // cdb-command:x a!function_names::*::generator*
index c0135de1219d37530e06cd8c0aa5724e2e20a299..5fa5ce80099358821d4f6f9b641d6524ac1da7eb 100644 (file)
 // cdb-command:g
 
 // cdb-command:dx int_int
-// cdb-check:int_int          [Type: generic_struct::AGenericStruct<i32, i32>]
+// cdb-check:int_int          [Type: generic_struct::AGenericStruct<i32,i32>]
 // cdb-check:[...]key              : 0 [Type: int]
 // cdb-check:[...]value            : 1 [Type: int]
 // cdb-command:dx int_float
-// cdb-check:int_float        [Type: generic_struct::AGenericStruct<i32, f64>]
+// cdb-check:int_float        [Type: generic_struct::AGenericStruct<i32,f64>]
 // cdb-check:[...]key              : 2 [Type: int]
 // cdb-check:[...]value            : 3.500000 [Type: double]
 // cdb-command:dx float_int
-// cdb-check:float_int        [Type: generic_struct::AGenericStruct<f64, i32>]
+// cdb-check:float_int        [Type: generic_struct::AGenericStruct<f64,i32>]
 // cdb-check:[...]key              : 4.500000 [Type: double]
 // cdb-check:[...]value            : 5 [Type: int]
 // cdb-command:dx float_int_float
-// cdb-check:float_int_float  [Type: generic_struct::AGenericStruct<f64, generic_struct::AGenericStruct<i32, f64> >]
+// cdb-check:float_int_float  [Type: generic_struct::AGenericStruct<f64,generic_struct::AGenericStruct<i32,f64> >]
 // cdb-check:[...]key              : 6.500000 [Type: double]
-// cdb-check:[...]value            [Type: generic_struct::AGenericStruct<i32, f64>]
+// cdb-check:[...]value            [Type: generic_struct::AGenericStruct<i32,f64>]
 
 
 #![feature(omit_gdb_pretty_printer_section)]
index f248fcd839122d4006df757e2c691932149bcbd1..9463f82c797496b5a05f9fde1f3622f3dd47c1c4 100644 (file)
@@ -87,8 +87,8 @@
 // cdb-check:    [+0x000] discriminant     : 0x[...] [Type: enum$<core::option::Option<alloc::string::String>, 1, [...], Some>::Discriminant$]
 
 // cdb-command: dx -r2 l,!
-// cdb-check:l,!              : $T2 [Type: enum$<core::result::Result<u32, enum$<msvc_pretty_enums::Empty> >, Ok>]
-// cdb-check:    [+0x000] Ok               [Type: enum$<core::result::Result<u32, enum$<msvc_pretty_enums::Empty> >, Ok>::Ok]
+// cdb-check:l,!              : $T2 [Type: enum$<core::result::Result<u32,enum$<msvc_pretty_enums::Empty> >, Ok>]
+// cdb-check:    [+0x000] Ok               [Type: enum$<core::result::Result<u32,enum$<msvc_pretty_enums::Empty> >, Ok>::Ok]
 // cdb-check:        [+0x000] __0              : 0x2a [Type: unsigned int]
 
 pub enum CStyleEnum {
index ede15578712578cd476dbf73100e473872887414..40bde8606996aaabdae5ec3d5cbd4fcb6233814c 100644 (file)
@@ -10,7 +10,7 @@
 // cdb-command: g
 
 // cdb-command: dx hash_set,d
-// cdb-check:hash_set,d [...] : { len=15 } [Type: [...]::HashSet<u64, [...]>]
+// cdb-check:hash_set,d [...] : { len=15 } [Type: [...]::HashSet<u64,[...]>]
 // cdb-check:    [len]            : 15 [Type: [...]]
 // cdb-check:    [capacity]       : [...]
 // cdb-check:    [[...]] [...]    : 0 [Type: u64]
@@ -44,7 +44,7 @@
 // cdb-check:    [[...]] [...]    : 14 [Type: u64]
 
 // cdb-command: dx hash_map,d
-// cdb-check:hash_map,d [...] : { len=15 } [Type: [...]::HashMap<u64, u64, [...]>]
+// cdb-check:hash_map,d [...] : { len=15 } [Type: [...]::HashMap<u64,u64,[...]>]
 // cdb-check:    [len]            : 15 [Type: [...]]
 // cdb-check:    [capacity]       : [...]
 // cdb-check:    ["0x0"]          : 0 [Type: unsigned __int64]
index d5a6e148b7a66e8b30348bdf687f6935869a18c2..a190a29eec2a59491f32fa85884e1bf8082d7f56 100644 (file)
@@ -79,7 +79,7 @@
 // cdb-check:    [3]              : 3 [Type: int]
 
 // cdb-command: dx vec,d
-// cdb-check:vec,d [...] : { len=4 } [Type: [...]::Vec<u64, alloc::alloc::Global>]
+// cdb-check:vec,d [...] : { len=4 } [Type: [...]::Vec<u64,alloc::alloc::Global>]
 // cdb-check:    [len]            : 4 [Type: [...]]
 // cdb-check:    [capacity]       : [...] [Type: [...]]
 // cdb-check:    [0]              : 4 [Type: unsigned __int64]
index a075c437c463b588a21b412819d19a3d62b7aef8..c0d905a6acc4ebd1ec6e668fc659809b975d2e92 100644 (file)
@@ -7,11 +7,11 @@
 // cdb-command: g
 
 // cdb-command: dx x,d
-// cdb-check:x,d              : Ok [Type: enum$<core::result::Result<i32, str> >]
+// cdb-check:x,d              : Ok [Type: enum$<core::result::Result<i32,str> >]
 // cdb-check:    [...] __0              : -3 [Type: int]
 
 // cdb-command: dx y
-// cdb-check:y                : Err [Type: enum$<core::result::Result<i32, str> >]
+// cdb-check:y                : Err [Type: enum$<core::result::Result<i32,str> >]
 // cdb-check:    [...] __0              : "Some error message" [Type: str]
 
 fn main()
index d1f322fa76cca23c17e0316540b32851f6161542..3497f0afb2cb0bd4447872ef8bb0ceb1f2d40111 100644 (file)
 // gdb-check:type = &mut dyn type_names::Trait2<type_names::mod1::mod2::Struct3, type_names::GenericStruct<usize, isize>>
 
 // gdb-command:whatis no_principal_trait
-// gdb-check:type = alloc::boxed::Box<dyn core::marker::Send + core::marker::Sync, alloc::alloc::Global>
+// gdb-check:type = alloc::boxed::Box<(dyn core::marker::Send + core::marker::Sync), alloc::alloc::Global>
+
+// gdb-command:whatis has_associated_type_trait
+// gdb-check:type = &(dyn type_names::Trait3<u32, AssocType=isize> + core::marker::Send)
+
 
 // BARE FUNCTIONS
 // gdb-command:whatis rust_fn
 // 0-sized structs appear to be optimized away in some cases, so only check the structs that do
 // actually appear.
 // cdb-command:dv /t *_struct
-// cdb-check:struct type_names::GenericStruct<enum$<type_names::mod1::Enum2>, f64> mut_generic_struct = [...]
+// cdb-check:struct type_names::GenericStruct<enum$<type_names::mod1::Enum2>,f64> mut_generic_struct = [...]
 
 // ENUMS
 // cdb-command:dv /t *_enum_*
 
 // BOX
 // cdb-command:dv /t box*
-// cdb-check:struct tuple$<alloc::boxed::Box<f32, alloc::alloc::Global>,i32> box1 = [...]
-// cdb-check:struct tuple$<alloc::boxed::Box<enum$<type_names::mod1::mod2::Enum3<f32> >, alloc::alloc::Global>,i32> box2 = [...]
+// cdb-check:struct tuple$<alloc::boxed::Box<f32,alloc::alloc::Global>,i32> box1 = [...]
+// cdb-check:struct tuple$<alloc::boxed::Box<enum$<type_names::mod1::mod2::Enum3<f32> >,alloc::alloc::Global>,i32> box2 = [...]
 
 // REFERENCES
 // cdb-command:dv /t *ref*
 // cdb-check:struct tuple$<ref$<type_names::Struct1>,i32> ref1 = [...]
-// cdb-check:struct tuple$<ref$<type_names::GenericStruct<char, type_names::Struct1> >,i32> ref2 = [...]
+// cdb-check:struct tuple$<ref$<type_names::GenericStruct<char,type_names::Struct1> >,i32> ref2 = [...]
 // cdb-check:struct tuple$<ref_mut$<type_names::Struct1>,i32> mut_ref1 = [...]
-// cdb-check:struct tuple$<ref_mut$<type_names::GenericStruct<enum$<type_names::mod1::Enum2>, f64> >,i32> mut_ref2 = [...]
+// cdb-check:struct tuple$<ref_mut$<type_names::GenericStruct<enum$<type_names::mod1::Enum2>,f64> >,i32> mut_ref2 = [...]
 
 // RAW POINTERS
 // cdb-command:dv /t *_ptr*
 // cdb-command:dv /t *vec*
 // cdb-check:struct tuple$<array$<type_names::Struct1,3>,i16> fixed_size_vec1 = [...]
 // cdb-check:struct tuple$<array$<usize,3>,i16> fixed_size_vec2 = [...]
-// cdb-check:struct alloc::vec::Vec<usize, alloc::alloc::Global> vec1 = [...]
-// cdb-check:struct alloc::vec::Vec<enum$<type_names::mod1::Enum2>, alloc::alloc::Global> vec2 = [...]
+// cdb-check:struct alloc::vec::Vec<usize,alloc::alloc::Global> vec1 = [...]
+// cdb-check:struct alloc::vec::Vec<enum$<type_names::mod1::Enum2>,alloc::alloc::Global> vec2 = [...]
 // cdb-command:dv /t slice*
 // cdb-check:struct slice$<usize> slice1 = [...]
 // cdb-check:struct slice$<enum$<type_names::mod1::Enum2> > slice2 = [...]
 
 // TRAITS
 // cdb-command:dv /t *_trait
-// cdb-check:struct ref_mut$<dyn$<type_names::Trait2<type_names::mod1::mod2::Struct3, type_names::GenericStruct<usize, isize> > > > generic_mut_ref_trait = [...]
-// cdb-check:struct ref$<dyn$<type_names::Trait2<type_names::Struct1, type_names::Struct1> > > generic_ref_trait = [...]
-// cdb-check:struct alloc::boxed::Box<dyn$<type_names::Trait2<i32, type_names::mod1::Struct2> >, alloc::alloc::Global> generic_box_trait = [...]
-// cdb-check:struct alloc::boxed::Box<dyn$<type_names::Trait1>, alloc::alloc::Global> box_trait = [...]
+// cdb-check:struct ref_mut$<dyn$<type_names::Trait2<type_names::mod1::mod2::Struct3,type_names::GenericStruct<usize,isize> > > > generic_mut_ref_trait = [...]
+// cdb-check:struct ref$<dyn$<type_names::Trait2<type_names::Struct1,type_names::Struct1> > > generic_ref_trait = [...]
+// cdb-check:struct alloc::boxed::Box<dyn$<type_names::Trait2<i32,type_names::mod1::Struct2> >,alloc::alloc::Global> generic_box_trait = [...]
+// cdb-check:struct alloc::boxed::Box<dyn$<type_names::Trait1>,alloc::alloc::Global> box_trait = [...]
 // cdb-check:struct ref$<dyn$<type_names::Trait1> > ref_trait = [...]
 // cdb-check:struct ref_mut$<dyn$<type_names::Trait1> > mut_ref_trait = [...]
-// cdb-check:struct alloc::boxed::Box<dyn$<core::marker::Send, core::marker::Sync>, alloc::alloc::Global> no_principal_trait = [...]
-// cdb-check:struct ref$<dyn$<type_names::Trait3> > has_associated_type_trait = struct ref$<dyn$<type_names::Trait3> >
+// cdb-check:struct alloc::boxed::Box<dyn$<core::marker::Send,core::marker::Sync>,alloc::alloc::Global> no_principal_trait = [...]
+// cdb-check:struct ref$<dyn$<type_names::Trait3<u32,assoc$<AssocType,isize> >,core::marker::Send> > has_associated_type_trait = struct ref$<dyn$<type_names::Trait3<u32,assoc$<AssocType,isize> >,core::marker::Send> >
 
 // BARE FUNCTIONS
 // cdb-command:dv /t *_fn*
-// cdb-check:struct tuple$<type_names::mod1::Struct2 (*)(type_names::GenericStruct<u16, u8>),usize> unsafe_fn_with_return_value = [...]
+// cdb-check:struct tuple$<type_names::mod1::Struct2 (*)(type_names::GenericStruct<u16,u8>),usize> unsafe_fn_with_return_value = [...]
 // cdb-check:struct tuple$<type_names::Struct1 (*)(),usize> extern_c_fn_with_return_value = [...]
 // cdb-check:struct tuple$<usize (*)(f64),usize> rust_fn_with_return_value = [...]
-// cdb-check:struct tuple$<void (*)(enum$<core::result::Result<char, f64> >),usize> unsafe_fn = [...]
+// cdb-check:struct tuple$<void (*)(enum$<core::result::Result<char,f64> >),usize> unsafe_fn = [...]
 // cdb-check:struct tuple$<void (*)(isize),usize> extern_c_fn = [...]
-// cdb-check:struct tuple$<void (*)(enum$<core::option::Option<isize> >, enum$<core::option::Option<ref$<type_names::mod1::Struct2> >, 1, [...], Some>),usize> rust_fn = [...]
+// cdb-check:struct tuple$<void (*)(enum$<core::option::Option<isize> >,enum$<core::option::Option<ref$<type_names::mod1::Struct2> >, 1, [...], Some>),usize> rust_fn = [...]
 // cdb-command:dv /t *_function*
 // cdb-check:struct tuple$<isize (*)(ptr_const$<u8>, ...),usize> variadic_function = [...]
 // cdb-check:struct tuple$<type_names::mod1::mod2::Struct3 (*)(type_names::mod1::mod2::Struct3),usize> generic_function_struct3 = [...]
@@ -306,14 +310,14 @@ fn dummy(&self) {}
 trait Trait2<T1, T2> {
     fn dummy(&self, _: T1, _: T2) {}
 }
-trait Trait3 {
+trait Trait3<T> {
     type AssocType;
-    fn dummy(&self) {}
+    fn dummy(&self) -> T { panic!() }
 }
 
 impl Trait1 for isize {}
 impl<T1, T2> Trait2<T1, T2> for isize {}
-impl Trait3 for isize {
+impl<T> Trait3<T> for isize {
     type AssocType = isize;
 }
 
@@ -404,8 +408,8 @@ fn main() {
     let ref_trait = &0_isize as &dyn Trait1;
     let mut mut_int1 = 0_isize;
     let mut_ref_trait = (&mut mut_int1) as &mut dyn Trait1;
-    let no_principal_trait = (box 0_isize) as Box<dyn Send + Sync>;
-    let has_associated_type_trait = &0_isize as &dyn Trait3<AssocType = isize>;
+    let no_principal_trait = (box 0_isize) as Box<(dyn Send + Sync)>;
+    let has_associated_type_trait = &0_isize as &(dyn Trait3<u32, AssocType = isize> + Send);
 
     let generic_box_trait = (box 0_isize) as Box<dyn Trait2<i32, mod1::Struct2>>;
     let generic_ref_trait = (&0_isize) as &dyn Trait2<Struct1, Struct1>;
index aa20d6aa4bf27b35accfeaed036ec6f0ebd77d1d..a9aad54162f110749cd45699c399452f27e61ed9 100644 (file)
@@ -2,4 +2,4 @@
 
 all:
        $(RUSTDOC) --output-format=json x.html 2>&1 | diff - output-format-json.stderr
-       $(RUSTC) --force-warns dead_code x.rs 2>&1 | diff - force-warns.stderr
+       $(RUSTC) --force-warn dead_code x.rs 2>&1 | diff - force-warn.stderr
diff --git a/src/test/run-make/unstable-flag-required/force-warn.stderr b/src/test/run-make/unstable-flag-required/force-warn.stderr
new file mode 100644 (file)
index 0000000..1b70dc8
--- /dev/null
@@ -0,0 +1,2 @@
+error: the `-Z unstable-options` flag must also be passed to enable the flag `--force-warn=lints`
+
diff --git a/src/test/run-make/unstable-flag-required/force-warns.stderr b/src/test/run-make/unstable-flag-required/force-warns.stderr
deleted file mode 100644 (file)
index e093619..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-error: the `-Z unstable-options` flag must also be passed to enable the flag `--force-warns=lints`
-
diff --git a/src/test/rustdoc-gui/default-settings.goml b/src/test/rustdoc-gui/default-settings.goml
new file mode 100644 (file)
index 0000000..68b674a
--- /dev/null
@@ -0,0 +1,8 @@
+// This test ensures that the default settings are correctly applied.
+//
+// The "settings" crate uses "ayu" as default setting, which is what we will
+// check.
+goto: file://|DOC_PATH|/settings/index.html
+// Wait a bit to be sure the default theme is applied.
+wait-for: 1000
+assert-css: ("body", {"background-color": "rgb(15, 20, 25)"})
diff --git a/src/test/rustdoc-gui/docblock-table-overflow.goml b/src/test/rustdoc-gui/docblock-table-overflow.goml
new file mode 100644 (file)
index 0000000..9ab7cd0
--- /dev/null
@@ -0,0 +1,9 @@
+// This test ensures that the type declaration content overflow is handled inside the <pre> directly.
+goto: file://|DOC_PATH|/lib2/long_table/struct.Foo.html
+// We set a fixed size so there is no chance of "random" resize.
+size: (1100, 800)
+// Logically, the ".docblock" and the "<p>" should have the same scroll width.
+compare-elements-property: (".top-doc .docblock", ".top-doc .docblock > p", ["scrollWidth"])
+assert-property: (".top-doc .docblock", {"scrollWidth": "816"})
+// However, since there is overflow in the <table>, its scroll width is bigger.
+assert-property: (".top-doc .docblock table", {"scrollWidth": "1573"})
diff --git a/src/test/rustdoc-gui/item-summary-table.goml b/src/test/rustdoc-gui/item-summary-table.goml
new file mode 100644 (file)
index 0000000..6bf4e28
--- /dev/null
@@ -0,0 +1,6 @@
+// This test ensures that <table> elements aren't display in items summary.
+goto: file://|DOC_PATH|/lib2/summary_table/index.html
+// We check that we picked the right item first.
+assert-text: (".item-table .item-left", "Foo")
+// Then we check that its summary is empty.
+assert-text: (".item-table .item-right", "")
diff --git a/src/test/rustdoc-gui/src/Cargo.lock b/src/test/rustdoc-gui/src/Cargo.lock
deleted file mode 100644 (file)
index a72ccff..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-# This file is automatically @generated by Cargo.
-# It is not intended for manual editing.
-version = 3
-
-[[package]]
-name = "implementors"
-version = "0.1.0"
-
-[[package]]
-name = "lib2"
-version = "0.1.0"
-dependencies = [
- "implementors",
-]
-
-[[package]]
-name = "test_docs"
-version = "0.1.0"
diff --git a/src/test/rustdoc-gui/src/Cargo.toml b/src/test/rustdoc-gui/src/Cargo.toml
deleted file mode 100644 (file)
index 9c8c0c6..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-[workspace]
-members = [
-    "test_docs",
-    "lib2",
-    "implementors",
-]
diff --git a/src/test/rustdoc-gui/src/implementors/Cargo.toml b/src/test/rustdoc-gui/src/implementors/Cargo.toml
deleted file mode 100644 (file)
index 7ef1052..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-[package]
-name = "implementors"
-version = "0.1.0"
-edition = "2018"
-
-[lib]
-path = "lib.rs"
diff --git a/src/test/rustdoc-gui/src/implementors/lib.rs b/src/test/rustdoc-gui/src/implementors/lib.rs
deleted file mode 100644 (file)
index 4b2f696..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-pub trait Whatever {
-    fn method() {}
-}
-
-pub struct Struct;
-
-impl Whatever for Struct {}
diff --git a/src/test/rustdoc-gui/src/lib2/Cargo.lock b/src/test/rustdoc-gui/src/lib2/Cargo.lock
new file mode 100644 (file)
index 0000000..a5873ce
--- /dev/null
@@ -0,0 +1,14 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 3
+
+[[package]]
+name = "implementors"
+version = "0.1.0"
+
+[[package]]
+name = "lib2"
+version = "0.1.0"
+dependencies = [
+ "implementors",
+]
index 6041a793f08dae9f952d45d2593edd69eb86563b..2e37f3f667a02f9ae583ede9650964a0e720d1fd 100644 (file)
@@ -7,4 +7,4 @@ edition = "2018"
 path = "lib.rs"
 
 [dependencies]
-implementors = { path = "../implementors" }
+implementors = { path = "./implementors" }
diff --git a/src/test/rustdoc-gui/src/lib2/implementors/Cargo.lock b/src/test/rustdoc-gui/src/lib2/implementors/Cargo.lock
new file mode 100644 (file)
index 0000000..cad99a9
--- /dev/null
@@ -0,0 +1,7 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 3
+
+[[package]]
+name = "implementors"
+version = "0.1.0"
diff --git a/src/test/rustdoc-gui/src/lib2/implementors/Cargo.toml b/src/test/rustdoc-gui/src/lib2/implementors/Cargo.toml
new file mode 100644 (file)
index 0000000..7ef1052
--- /dev/null
@@ -0,0 +1,7 @@
+[package]
+name = "implementors"
+version = "0.1.0"
+edition = "2018"
+
+[lib]
+path = "lib.rs"
diff --git a/src/test/rustdoc-gui/src/lib2/implementors/lib.rs b/src/test/rustdoc-gui/src/lib2/implementors/lib.rs
new file mode 100644 (file)
index 0000000..4b2f696
--- /dev/null
@@ -0,0 +1,7 @@
+pub trait Whatever {
+    fn method() {}
+}
+
+pub struct Struct;
+
+impl Whatever for Struct {}
index cd00348cad3d1b5b81ce24ea8706fcce9567fb3f..36373d24971c992a76d2532f0ff8dbad6ac29552 100644 (file)
@@ -57,3 +57,19 @@ pub mod long_trait {
     pub trait ALongNameBecauseItHelpsTestingTheCurrentProblem: DerefMut<Target = u32>
         + From<u128> + Send + Sync + AsRef<str> + 'static {}
 }
+
+pub mod long_table {
+    /// | This::is::a::kinda::very::long::header::number::one | This::is::a::kinda::very::long::header::number::two | This::is::a::kinda::very::long::header::number::one | This::is::a::kinda::very::long::header::number::two |
+    /// | ----------- | ----------- | ----------- | ----------- |
+    /// | This::is::a::kinda::long::content::number::one | This::is::a::kinda::very::long::content::number::two | This::is::a::kinda::long::content::number::one | This::is::a::kinda::very::long::content::number::two |
+    ///
+    /// I wanna sqdkfnqds f dsqf qds f dsqf dsq f dsq f qds f qds f qds f dsqq f dsf sqdf dsq fds f dsq f dq f ds fq sd fqds f dsq f sqd fsq df sd fdsqfqsd fdsq f dsq f dsqfd s dfq
+    pub struct Foo;
+}
+
+pub mod summary_table {
+    /// | header 1 | header 2 |
+    /// | -------- | -------- |
+    /// | content | content |
+    pub struct Foo;
+}
diff --git a/src/test/rustdoc-gui/src/lib2/src/lib.rs b/src/test/rustdoc-gui/src/lib2/src/lib.rs
deleted file mode 100644 (file)
index 31e1bb2..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-#[cfg(test)]
-mod tests {
-    #[test]
-    fn it_works() {
-        assert_eq!(2 + 2, 4);
-    }
-}
diff --git a/src/test/rustdoc-gui/src/settings/.cargo/config.toml b/src/test/rustdoc-gui/src/settings/.cargo/config.toml
new file mode 100644 (file)
index 0000000..bbb8d11
--- /dev/null
@@ -0,0 +1,2 @@
+[build]
+rustdocflags = ["--default-theme", "ayu"]
diff --git a/src/test/rustdoc-gui/src/settings/Cargo.lock b/src/test/rustdoc-gui/src/settings/Cargo.lock
new file mode 100644 (file)
index 0000000..6f0de1a
--- /dev/null
@@ -0,0 +1,7 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 3
+
+[[package]]
+name = "settings"
+version = "0.1.0"
diff --git a/src/test/rustdoc-gui/src/settings/Cargo.toml b/src/test/rustdoc-gui/src/settings/Cargo.toml
new file mode 100644 (file)
index 0000000..c8a211a
--- /dev/null
@@ -0,0 +1,7 @@
+[package]
+name = "settings"
+version = "0.1.0"
+edition = "2018"
+
+[lib]
+path = "lib.rs"
diff --git a/src/test/rustdoc-gui/src/settings/lib.rs b/src/test/rustdoc-gui/src/settings/lib.rs
new file mode 100644 (file)
index 0000000..b76b432
--- /dev/null
@@ -0,0 +1 @@
+pub fn foo() {}
diff --git a/src/test/rustdoc-gui/src/test_docs/Cargo.lock b/src/test/rustdoc-gui/src/test_docs/Cargo.lock
new file mode 100644 (file)
index 0000000..6b80f6e
--- /dev/null
@@ -0,0 +1,7 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 3
+
+[[package]]
+name = "test_docs"
+version = "0.1.0"
index ad814b82352c3fed39f4d6d0e4a5e7f03e6ba8be..b105f47d751718980d60564cb43eab0dc4af562d 100644 (file)
@@ -14,7 +14,7 @@ error: unknown lint: `rustdoc::x`
   --> $DIR/unknown-renamed-lints.rs:7:9
    |
 LL | #![deny(rustdoc::x)]
-   |         ^^^^^^^^^^
+   |         ^^^^^^^^^^ help: did you mean: `rustdoc::all`
 
 error: lint `intra_doc_link_resolution_failure` has been renamed to `rustdoc::broken_intra_doc_links`
   --> $DIR/unknown-renamed-lints.rs:9:9
diff --git a/src/test/rustdoc/default-theme.rs b/src/test/rustdoc/default-theme.rs
new file mode 100644 (file)
index 0000000..ecb8f0b
--- /dev/null
@@ -0,0 +1,7 @@
+// compile-flags: --default-theme ayu
+
+// @has default_theme/index.html
+// @has - '//script[@id="default-settings"]/@data-theme' 'ayu'
+// @has - '//script[@id="default-settings"]/@data-use_system_theme' 'false'
+
+pub fn whatever() {}
index 6e3c0b4c681f7c6e3b8604eb4a67f1465fe3e3e4..167858b6065f9b3f2b587016966f26ce2c8c6400 100644 (file)
@@ -9,7 +9,7 @@ pub struct PubStruct {
 
 // @has 'toggle_item_contents/struct.BigPubStruct.html'
 // @count - '//details[@class="rustdoc-toggle type-contents-toggle"]' 1
-// @has - '//details[@class="rustdoc-toggle type-contents-toggle"]' 'Show fields'
+// @has - '//details[@class="rustdoc-toggle type-contents-toggle"]' 'Show 13 fields'
 pub struct BigPubStruct {
     pub a: usize,
     pub b: usize,
@@ -28,7 +28,7 @@ pub struct BigPubStruct {
 
 // @has 'toggle_item_contents/union.BigUnion.html'
 // @count - '//details[@class="rustdoc-toggle type-contents-toggle"]' 1
-// @has - '//details[@class="rustdoc-toggle type-contents-toggle"]' 'Show fields'
+// @has - '//details[@class="rustdoc-toggle type-contents-toggle"]' 'Show 13 fields'
 pub union BigUnion {
     pub a: usize,
     pub b: usize,
@@ -63,7 +63,7 @@ pub struct PrivStruct {
 
 // @has 'toggle_item_contents/enum.Enum.html'
 // @count - '//details[@class="rustdoc-toggle type-contents-toggle"]' 1
-// @has - '//details[@class="rustdoc-toggle type-contents-toggle"]' 'Show fields'
+// @has - '//details[@class="rustdoc-toggle type-contents-toggle"]' 'Show fields'
 pub enum Enum {
     A, B, C,
     D {
@@ -72,9 +72,19 @@ pub enum Enum {
     }
 }
 
+// @has 'toggle_item_contents/enum.EnumStructVariant.html'
+// @count - '//details[@class="rustdoc-toggle type-contents-toggle"]' 1
+// @has - '//details[@class="rustdoc-toggle type-contents-toggle"]' 'Show 1 field'
+pub enum EnumStructVariant {
+    A, B, C,
+    D {
+        a: u8,
+    }
+}
+
 // @has 'toggle_item_contents/enum.LargeEnum.html'
 // @count - '//details[@class="rustdoc-toggle type-contents-toggle"]' 1
-// @has - '//details[@class="rustdoc-toggle type-contents-toggle"]' 'Show variants'
+// @has - '//details[@class="rustdoc-toggle type-contents-toggle"]' 'Show 13 variants'
 pub enum LargeEnum {
     A, B, C, D, E, F(u8), G, H, I, J, K, L, M
 }
@@ -90,7 +100,7 @@ pub trait Trait {
 
 // @has 'toggle_item_contents/trait.GinormousTrait.html'
 // @count - '//details[@class="rustdoc-toggle type-contents-toggle"]' 1
-// @has - '//details[@class="rustdoc-toggle type-contents-toggle"]' 'Show associated items'
+// @has - '//details[@class="rustdoc-toggle type-contents-toggle"]' 'Show 16 associated items'
 pub trait GinormousTrait {
     type A;
     type B;
@@ -113,7 +123,7 @@ pub trait GinormousTrait {
 
 // @has 'toggle_item_contents/trait.HugeTrait.html'
 // @count - '//details[@class="rustdoc-toggle type-contents-toggle"]' 1
-// @has - '//details[@class="rustdoc-toggle type-contents-toggle"]' 'Show associated constants and methods'
+// @has - '//details[@class="rustdoc-toggle type-contents-toggle"]' 'Show 12 associated constants and 2 methods'
 pub trait HugeTrait {
     type A;
     const M: usize = 1;
@@ -133,9 +143,30 @@ pub trait HugeTrait {
     fn bar();
 }
 
+// @has 'toggle_item_contents/trait.GiganticTrait.html'
+// @count - '//details[@class="rustdoc-toggle type-contents-toggle"]' 1
+// @has - '//details[@class="rustdoc-toggle type-contents-toggle"]' 'Show 1 associated constant and 1 method'
+pub trait GiganticTrait {
+    type A;
+    type B;
+    type C;
+    type D;
+    type E;
+    type F;
+    type G;
+    type H;
+    type I;
+    type J;
+    type K;
+    type L;
+    const M: usize = 1;
+    #[must_use]
+    fn foo();
+}
+
 // @has 'toggle_item_contents/trait.BigTrait.html'
 // @count - '//details[@class="rustdoc-toggle type-contents-toggle"]' 1
-// @has - '//details[@class="rustdoc-toggle type-contents-toggle"]' 'Show methods'
+// @has - '//details[@class="rustdoc-toggle type-contents-toggle"]' 'Show 14 methods'
 pub trait BigTrait {
     type A;
     #[must_use]
index 2f1debe25b74fddb5563fe44345a4c267fbaa159..c7853f5275e01768b302490d51f6f59686c69094 100644 (file)
@@ -56,6 +56,8 @@ LL | #[message = "This error has a field, and references {name}"]
 error: invalid format string: expected `'}'` but string was terminated
   --> $DIR/session-derive-errors.rs:116:1
    |
+LL | #[derive(SessionDiagnostic)]
+   |          ----------------- in this derive macro expansion
 LL | #[error = "E0123"]
    |               - because of this opening brace
 LL | #[message = "This is missing a closing brace: {name"]
@@ -67,6 +69,9 @@ LL | #[message = "This is missing a closing brace: {name"]
 error: invalid format string: unmatched `}` found
   --> $DIR/session-derive-errors.rs:125:1
    |
+LL | #[derive(SessionDiagnostic)]
+   |          ----------------- in this derive macro expansion
+LL | #[error = "E0123"]
 LL | #[message = "This is missing an opening brace: name}"]
    | ^ unmatched `}` in format string
    |
index 0851e1a5e9cf7b739f59a6973cc372463b796c6d..628b48a45d76d6b19604f4a47537b4cbb7a4e2d6 100644 (file)
@@ -1,37 +1,61 @@
 error[E0277]: the trait bound `usize: GlobalAlloc` is not satisfied
   --> $DIR/not-an-allocator.rs:2:1
    |
+LL | #[global_allocator]
+   | ------------------- in this procedural macro expansion
 LL | static A: usize = 0;
    | ^^^^^^^^^^^^^^^^^^^^ the trait `GlobalAlloc` is not implemented for `usize`
    |
-   = note: required by `std::alloc::GlobalAlloc::alloc`
+note: required by `std::alloc::GlobalAlloc::alloc`
+  --> $SRC_DIR/core/src/alloc/global.rs:LL:COL
+   |
+LL |     unsafe fn alloc(&self, layout: Layout) -> *mut u8;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: this error originates in the attribute macro `global_allocator` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0277]: the trait bound `usize: GlobalAlloc` is not satisfied
   --> $DIR/not-an-allocator.rs:2:1
    |
+LL | #[global_allocator]
+   | ------------------- in this procedural macro expansion
 LL | static A: usize = 0;
    | ^^^^^^^^^^^^^^^^^^^^ the trait `GlobalAlloc` is not implemented for `usize`
    |
-   = note: required by `std::alloc::GlobalAlloc::dealloc`
+note: required by `std::alloc::GlobalAlloc::dealloc`
+  --> $SRC_DIR/core/src/alloc/global.rs:LL:COL
+   |
+LL |     unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: this error originates in the attribute macro `global_allocator` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0277]: the trait bound `usize: GlobalAlloc` is not satisfied
   --> $DIR/not-an-allocator.rs:2:1
    |
+LL | #[global_allocator]
+   | ------------------- in this procedural macro expansion
 LL | static A: usize = 0;
    | ^^^^^^^^^^^^^^^^^^^^ the trait `GlobalAlloc` is not implemented for `usize`
    |
-   = note: required by `std::alloc::GlobalAlloc::realloc`
+note: required by `std::alloc::GlobalAlloc::realloc`
+  --> $SRC_DIR/core/src/alloc/global.rs:LL:COL
+   |
+LL |     unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 {
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: this error originates in the attribute macro `global_allocator` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0277]: the trait bound `usize: GlobalAlloc` is not satisfied
   --> $DIR/not-an-allocator.rs:2:1
    |
+LL | #[global_allocator]
+   | ------------------- in this procedural macro expansion
 LL | static A: usize = 0;
    | ^^^^^^^^^^^^^^^^^^^^ the trait `GlobalAlloc` is not implemented for `usize`
    |
-   = note: required by `std::alloc::GlobalAlloc::alloc_zeroed`
+note: required by `std::alloc::GlobalAlloc::alloc_zeroed`
+  --> $SRC_DIR/core/src/alloc/global.rs:LL:COL
+   |
+LL |     unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 {
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: this error originates in the attribute macro `global_allocator` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: aborting due to 4 previous errors
index dbf1054f1068cfb394b5c27255b2a6eee88d905d..7a914c2a3907c673887f791bcc81458690230b7a 100644 (file)
@@ -4,6 +4,7 @@ error: cannot define multiple global allocators
 LL | static A: System = System;
    | -------------------------- previous global allocator defined here
 LL | #[global_allocator]
+   | ------------------- in this procedural macro expansion
 LL | static B: System = System;
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot define a new global allocator
    |
index 2fdfa3da3086c812adf4dfa7f612c0b2b6742db8..ff56d112c8184254fd9645f52a097180504f37b9 100644 (file)
@@ -1,11 +1,14 @@
 error[E0277]: the trait bound `i32: Foo` is not satisfied
   --> $DIR/associated-const-array-len.rs:5:16
    |
-LL |     const ID: usize;
-   |     ---------------- required by `Foo::ID`
-...
 LL | const X: [i32; <i32 as Foo>::ID] = [0, 1, 2];
    |                ^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `i32`
+   |
+note: required by `Foo::ID`
+  --> $DIR/associated-const-array-len.rs:2:5
+   |
+LL |     const ID: usize;
+   |     ^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
index 1b9d7ac7e6c3f2e0d6e5247ca84e8b7bf09ee7b8..aa356c596f8a05586ff3d63f9aa68418ca31b4d5 100644 (file)
@@ -1,6 +1,9 @@
 error[E0624]: associated constant `ID` is private
   --> $DIR/associated-const-private-impl.rs:13:30
    |
+LL |             const ID: i32 = 1;
+   |             ------------------ private associated constant defined here
+...
 LL |     assert_eq!(1, bar1::Foo::ID);
    |                              ^^ private associated constant
 
index 34e947030a072ff8b693e7bdc83492721c489c10..cea56cd5946c969ddbd9fb6d6d1a87c61b0f14cc 100644 (file)
@@ -1,9 +1,6 @@
 error[E0283]: type annotations needed
   --> $DIR/issue-63496.rs:4:21
    |
-LL |     const C: usize;
-   |     --------------- required by `A::C`
-LL | 
 LL |     fn f() -> ([u8; A::C], [u8; A::C]);
    |                     ^^^^
    |                     |
@@ -12,13 +9,15 @@ LL |     fn f() -> ([u8; A::C], [u8; A::C]);
    |
    = note: cannot satisfy `_: A`
    = note: associated constants cannot be accessed directly on a `trait`, they can only be accessed through a specific `impl`
+note: required by `A::C`
+  --> $DIR/issue-63496.rs:2:5
+   |
+LL |     const C: usize;
+   |     ^^^^^^^^^^^^^^^
 
 error[E0283]: type annotations needed
   --> $DIR/issue-63496.rs:4:33
    |
-LL |     const C: usize;
-   |     --------------- required by `A::C`
-LL | 
 LL |     fn f() -> ([u8; A::C], [u8; A::C]);
    |                                 ^^^^
    |                                 |
@@ -27,6 +26,11 @@ LL |     fn f() -> ([u8; A::C], [u8; A::C]);
    |
    = note: cannot satisfy `_: A`
    = note: associated constants cannot be accessed directly on a `trait`, they can only be accessed through a specific `impl`
+note: required by `A::C`
+  --> $DIR/issue-63496.rs:2:5
+   |
+LL |     const C: usize;
+   |     ^^^^^^^^^^^^^^^
 
 error: aborting due to 2 previous errors
 
index 92d74e38cfa8db81a4164e62c0a3374b293a02df..33ab4bb967a9704135fa83e75bb38cff50417d56 100644 (file)
@@ -16,8 +16,6 @@ LL |     const X: usize;
 error[E0283]: type annotations needed
   --> $DIR/issue-48027.rs:3:32
    |
-LL |     const X: usize;
-   |     --------------- required by `Bar::X`
 LL |     fn return_n(&self) -> [u8; Bar::X];
    |                                ^^^^^^
    |                                |
@@ -26,6 +24,11 @@ LL |     fn return_n(&self) -> [u8; Bar::X];
    |
    = note: cannot satisfy `_: Bar`
    = note: associated constants cannot be accessed directly on a `trait`, they can only be accessed through a specific `impl`
+note: required by `Bar::X`
+  --> $DIR/issue-48027.rs:2:5
+   |
+LL |     const X: usize;
+   |     ^^^^^^^^^^^^^^^
 
 error: aborting due to 2 previous errors
 
index bd3cac1f887bf10748b0c458dda40156098e87d8..bffa5150fe1ce80bde0a549cdf3fe230c03319f4 100644 (file)
@@ -7,16 +7,8 @@ LL | #![cfg_attr(full_tait, feature(type_alias_impl_trait))]
    = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #63063 <https://github.com/rust-lang/rust/issues/63063> for more information
 
-warning: the feature `impl_trait_in_bindings` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/duplicate.rs:6:12
-   |
-LL | #![feature(impl_trait_in_bindings)]
-   |            ^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
-
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:11:36
+  --> $DIR/duplicate.rs:10:36
    |
 LL | struct SI1<T: Iterator<Item: Copy, Item: Send>> { f: T }
    |                        ----------  ^^^^^^^^^^ re-bound here
@@ -24,7 +16,7 @@ LL | struct SI1<T: Iterator<Item: Copy, Item: Send>> { f: T }
    |                        `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:13:36
+  --> $DIR/duplicate.rs:12:36
    |
 LL | struct SI2<T: Iterator<Item: Copy, Item: Copy>> { f: T }
    |                        ----------  ^^^^^^^^^^ re-bound here
@@ -32,7 +24,7 @@ LL | struct SI2<T: Iterator<Item: Copy, Item: Copy>> { f: T }
    |                        `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:15:39
+  --> $DIR/duplicate.rs:14:39
    |
 LL | struct SI3<T: Iterator<Item: 'static, Item: 'static>> { f: T }
    |                        -------------  ^^^^^^^^^^^^^ re-bound here
@@ -40,7 +32,7 @@ LL | struct SI3<T: Iterator<Item: 'static, Item: 'static>> { f: T }
    |                        `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:17:45
+  --> $DIR/duplicate.rs:16:45
    |
 LL | struct SW1<T> where T: Iterator<Item: Copy, Item: Send> { f: T }
    |                                 ----------  ^^^^^^^^^^ re-bound here
@@ -48,7 +40,7 @@ LL | struct SW1<T> where T: Iterator<Item: Copy, Item: Send> { f: T }
    |                                 `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:19:45
+  --> $DIR/duplicate.rs:18:45
    |
 LL | struct SW2<T> where T: Iterator<Item: Copy, Item: Copy> { f: T }
    |                                 ----------  ^^^^^^^^^^ re-bound here
@@ -56,7 +48,7 @@ LL | struct SW2<T> where T: Iterator<Item: Copy, Item: Copy> { f: T }
    |                                 `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:21:48
+  --> $DIR/duplicate.rs:20:48
    |
 LL | struct SW3<T> where T: Iterator<Item: 'static, Item: 'static> { f: T }
    |                                 -------------  ^^^^^^^^^^^^^ re-bound here
@@ -64,7 +56,7 @@ LL | struct SW3<T> where T: Iterator<Item: 'static, Item: 'static> { f: T }
    |                                 `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:24:34
+  --> $DIR/duplicate.rs:23:34
    |
 LL | enum EI1<T: Iterator<Item: Copy, Item: Send>> { V(T) }
    |                      ----------  ^^^^^^^^^^ re-bound here
@@ -72,7 +64,7 @@ LL | enum EI1<T: Iterator<Item: Copy, Item: Send>> { V(T) }
    |                      `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:26:34
+  --> $DIR/duplicate.rs:25:34
    |
 LL | enum EI2<T: Iterator<Item: Copy, Item: Copy>> { V(T) }
    |                      ----------  ^^^^^^^^^^ re-bound here
@@ -80,7 +72,7 @@ LL | enum EI2<T: Iterator<Item: Copy, Item: Copy>> { V(T) }
    |                      `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:28:37
+  --> $DIR/duplicate.rs:27:37
    |
 LL | enum EI3<T: Iterator<Item: 'static, Item: 'static>> { V(T) }
    |                      -------------  ^^^^^^^^^^^^^ re-bound here
@@ -88,7 +80,7 @@ LL | enum EI3<T: Iterator<Item: 'static, Item: 'static>> { V(T) }
    |                      `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:30:43
+  --> $DIR/duplicate.rs:29:43
    |
 LL | enum EW1<T> where T: Iterator<Item: Copy, Item: Send> { V(T) }
    |                               ----------  ^^^^^^^^^^ re-bound here
@@ -96,7 +88,7 @@ LL | enum EW1<T> where T: Iterator<Item: Copy, Item: Send> { V(T) }
    |                               `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:32:43
+  --> $DIR/duplicate.rs:31:43
    |
 LL | enum EW2<T> where T: Iterator<Item: Copy, Item: Copy> { V(T) }
    |                               ----------  ^^^^^^^^^^ re-bound here
@@ -104,7 +96,7 @@ LL | enum EW2<T> where T: Iterator<Item: Copy, Item: Copy> { V(T) }
    |                               `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:34:46
+  --> $DIR/duplicate.rs:33:46
    |
 LL | enum EW3<T> where T: Iterator<Item: 'static, Item: 'static> { V(T) }
    |                               -------------  ^^^^^^^^^^^^^ re-bound here
@@ -112,7 +104,7 @@ LL | enum EW3<T> where T: Iterator<Item: 'static, Item: 'static> { V(T) }
    |                               `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:37:35
+  --> $DIR/duplicate.rs:36:35
    |
 LL | union UI1<T: Iterator<Item: Copy, Item: Send>> { f: T }
    |                       ----------  ^^^^^^^^^^ re-bound here
@@ -120,7 +112,7 @@ LL | union UI1<T: Iterator<Item: Copy, Item: Send>> { f: T }
    |                       `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:39:35
+  --> $DIR/duplicate.rs:38:35
    |
 LL | union UI2<T: Iterator<Item: Copy, Item: Copy>> { f: T }
    |                       ----------  ^^^^^^^^^^ re-bound here
@@ -128,7 +120,7 @@ LL | union UI2<T: Iterator<Item: Copy, Item: Copy>> { f: T }
    |                       `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:41:38
+  --> $DIR/duplicate.rs:40:38
    |
 LL | union UI3<T: Iterator<Item: 'static, Item: 'static>> { f: T }
    |                       -------------  ^^^^^^^^^^^^^ re-bound here
@@ -136,7 +128,7 @@ LL | union UI3<T: Iterator<Item: 'static, Item: 'static>> { f: T }
    |                       `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:43:44
+  --> $DIR/duplicate.rs:42:44
    |
 LL | union UW1<T> where T: Iterator<Item: Copy, Item: Send> { f: T }
    |                                ----------  ^^^^^^^^^^ re-bound here
@@ -144,7 +136,7 @@ LL | union UW1<T> where T: Iterator<Item: Copy, Item: Send> { f: T }
    |                                `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:45:44
+  --> $DIR/duplicate.rs:44:44
    |
 LL | union UW2<T> where T: Iterator<Item: Copy, Item: Copy> { f: T }
    |                                ----------  ^^^^^^^^^^ re-bound here
@@ -152,7 +144,7 @@ LL | union UW2<T> where T: Iterator<Item: Copy, Item: Copy> { f: T }
    |                                `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:47:47
+  --> $DIR/duplicate.rs:46:47
    |
 LL | union UW3<T> where T: Iterator<Item: 'static, Item: 'static> { f: T }
    |                                -------------  ^^^^^^^^^^^^^ re-bound here
@@ -160,7 +152,7 @@ LL | union UW3<T> where T: Iterator<Item: 'static, Item: 'static> { f: T }
    |                                `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:50:32
+  --> $DIR/duplicate.rs:49:32
    |
 LL | fn FI1<T: Iterator<Item: Copy, Item: Send>>() {}
    |                    ----------  ^^^^^^^^^^ re-bound here
@@ -168,7 +160,7 @@ LL | fn FI1<T: Iterator<Item: Copy, Item: Send>>() {}
    |                    `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:52:32
+  --> $DIR/duplicate.rs:51:32
    |
 LL | fn FI2<T: Iterator<Item: Copy, Item: Copy>>() {}
    |                    ----------  ^^^^^^^^^^ re-bound here
@@ -176,7 +168,7 @@ LL | fn FI2<T: Iterator<Item: Copy, Item: Copy>>() {}
    |                    `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:54:35
+  --> $DIR/duplicate.rs:53:35
    |
 LL | fn FI3<T: Iterator<Item: 'static, Item: 'static>>() {}
    |                    -------------  ^^^^^^^^^^^^^ re-bound here
@@ -184,7 +176,7 @@ LL | fn FI3<T: Iterator<Item: 'static, Item: 'static>>() {}
    |                    `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:56:43
+  --> $DIR/duplicate.rs:55:43
    |
 LL | fn FW1<T>() where T: Iterator<Item: Copy, Item: Send> {}
    |                               ----------  ^^^^^^^^^^ re-bound here
@@ -192,7 +184,7 @@ LL | fn FW1<T>() where T: Iterator<Item: Copy, Item: Send> {}
    |                               `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:58:43
+  --> $DIR/duplicate.rs:57:43
    |
 LL | fn FW2<T>() where T: Iterator<Item: Copy, Item: Copy> {}
    |                               ----------  ^^^^^^^^^^ re-bound here
@@ -200,7 +192,7 @@ LL | fn FW2<T>() where T: Iterator<Item: Copy, Item: Copy> {}
    |                               `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:60:46
+  --> $DIR/duplicate.rs:59:46
    |
 LL | fn FW3<T>() where T: Iterator<Item: 'static, Item: 'static> {}
    |                               -------------  ^^^^^^^^^^^^^ re-bound here
@@ -208,7 +200,7 @@ LL | fn FW3<T>() where T: Iterator<Item: 'static, Item: 'static> {}
    |                               `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:66:40
+  --> $DIR/duplicate.rs:65:40
    |
 LL | fn FAPIT1(_: impl Iterator<Item: Copy, Item: Send>) {}
    |                            ----------  ^^^^^^^^^^ re-bound here
@@ -216,7 +208,7 @@ LL | fn FAPIT1(_: impl Iterator<Item: Copy, Item: Send>) {}
    |                            `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:68:40
+  --> $DIR/duplicate.rs:67:40
    |
 LL | fn FAPIT2(_: impl Iterator<Item: Copy, Item: Copy>) {}
    |                            ----------  ^^^^^^^^^^ re-bound here
@@ -224,7 +216,7 @@ LL | fn FAPIT2(_: impl Iterator<Item: Copy, Item: Copy>) {}
    |                            `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:70:43
+  --> $DIR/duplicate.rs:69:43
    |
 LL | fn FAPIT3(_: impl Iterator<Item: 'static, Item: 'static>) {}
    |                            -------------  ^^^^^^^^^^^^^ re-bound here
@@ -232,79 +224,7 @@ LL | fn FAPIT3(_: impl Iterator<Item: 'static, Item: 'static>) {}
    |                            `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:73:39
-   |
-LL | const CIT1: impl Iterator<Item: Copy, Item: Send> = iter::empty();
-   |                           ----------  ^^^^^^^^^^ re-bound here
-   |                           |
-   |                           `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:75:39
-   |
-LL | const CIT2: impl Iterator<Item: Copy, Item: Copy> = iter::empty();
-   |                           ----------  ^^^^^^^^^^ re-bound here
-   |                           |
-   |                           `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:77:42
-   |
-LL | const CIT3: impl Iterator<Item: 'static, Item: 'static> = iter::empty();
-   |                           -------------  ^^^^^^^^^^^^^ re-bound here
-   |                           |
-   |                           `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:79:40
-   |
-LL | static SIT1: impl Iterator<Item: Copy, Item: Send> = iter::empty();
-   |                            ----------  ^^^^^^^^^^ re-bound here
-   |                            |
-   |                            `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:81:40
-   |
-LL | static SIT2: impl Iterator<Item: Copy, Item: Copy> = iter::empty();
-   |                            ----------  ^^^^^^^^^^ re-bound here
-   |                            |
-   |                            `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:83:43
-   |
-LL | static SIT3: impl Iterator<Item: 'static, Item: 'static> = iter::empty();
-   |                            -------------  ^^^^^^^^^^^^^ re-bound here
-   |                            |
-   |                            `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:86:46
-   |
-LL | fn lit1() { let _: impl Iterator<Item: Copy, Item: Send> = iter::empty(); }
-   |                                  ----------  ^^^^^^^^^^ re-bound here
-   |                                  |
-   |                                  `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:88:46
-   |
-LL | fn lit2() { let _: impl Iterator<Item: Copy, Item: Copy> = iter::empty(); }
-   |                                  ----------  ^^^^^^^^^^ re-bound here
-   |                                  |
-   |                                  `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:90:49
-   |
-LL | fn lit3() { let _: impl Iterator<Item: 'static, Item: 'static> = iter::empty(); }
-   |                                  -------------  ^^^^^^^^^^^^^ re-bound here
-   |                                  |
-   |                                  `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:93:35
+  --> $DIR/duplicate.rs:72:35
    |
 LL | type TAI1<T: Iterator<Item: Copy, Item: Send>> = T;
    |                       ----------  ^^^^^^^^^^ re-bound here
@@ -312,7 +232,7 @@ LL | type TAI1<T: Iterator<Item: Copy, Item: Send>> = T;
    |                       `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:95:35
+  --> $DIR/duplicate.rs:74:35
    |
 LL | type TAI2<T: Iterator<Item: Copy, Item: Copy>> = T;
    |                       ----------  ^^^^^^^^^^ re-bound here
@@ -320,7 +240,7 @@ LL | type TAI2<T: Iterator<Item: Copy, Item: Copy>> = T;
    |                       `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:97:38
+  --> $DIR/duplicate.rs:76:38
    |
 LL | type TAI3<T: Iterator<Item: 'static, Item: 'static>> = T;
    |                       -------------  ^^^^^^^^^^^^^ re-bound here
@@ -328,7 +248,7 @@ LL | type TAI3<T: Iterator<Item: 'static, Item: 'static>> = T;
    |                       `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:99:44
+  --> $DIR/duplicate.rs:78:44
    |
 LL | type TAW1<T> where T: Iterator<Item: Copy, Item: Send> = T;
    |                                ----------  ^^^^^^^^^^ re-bound here
@@ -336,7 +256,7 @@ LL | type TAW1<T> where T: Iterator<Item: Copy, Item: Send> = T;
    |                                `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:101:44
+  --> $DIR/duplicate.rs:80:44
    |
 LL | type TAW2<T> where T: Iterator<Item: Copy, Item: Copy> = T;
    |                                ----------  ^^^^^^^^^^ re-bound here
@@ -344,7 +264,7 @@ LL | type TAW2<T> where T: Iterator<Item: Copy, Item: Copy> = T;
    |                                `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:103:47
+  --> $DIR/duplicate.rs:82:47
    |
 LL | type TAW3<T> where T: Iterator<Item: 'static, Item: 'static> = T;
    |                                -------------  ^^^^^^^^^^^^^ re-bound here
@@ -352,7 +272,7 @@ LL | type TAW3<T> where T: Iterator<Item: 'static, Item: 'static> = T;
    |                                `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:106:36
+  --> $DIR/duplicate.rs:85:36
    |
 LL | type ETAI1<T: Iterator<Item: Copy, Item: Send>> = impl Copy;
    |                        ----------  ^^^^^^^^^^ re-bound here
@@ -360,7 +280,7 @@ LL | type ETAI1<T: Iterator<Item: Copy, Item: Send>> = impl Copy;
    |                        `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:108:36
+  --> $DIR/duplicate.rs:87:36
    |
 LL | type ETAI2<T: Iterator<Item: Copy, Item: Copy>> = impl Copy;
    |                        ----------  ^^^^^^^^^^ re-bound here
@@ -368,7 +288,7 @@ LL | type ETAI2<T: Iterator<Item: Copy, Item: Copy>> = impl Copy;
    |                        `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:110:39
+  --> $DIR/duplicate.rs:89:39
    |
 LL | type ETAI3<T: Iterator<Item: 'static, Item: 'static>> = impl Copy;
    |                        -------------  ^^^^^^^^^^^^^ re-bound here
@@ -376,7 +296,7 @@ LL | type ETAI3<T: Iterator<Item: 'static, Item: 'static>> = impl Copy;
    |                        `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:112:40
+  --> $DIR/duplicate.rs:91:40
    |
 LL | type ETAI4 = impl Iterator<Item: Copy, Item: Send>;
    |                            ----------  ^^^^^^^^^^ re-bound here
@@ -384,7 +304,7 @@ LL | type ETAI4 = impl Iterator<Item: Copy, Item: Send>;
    |                            `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:114:40
+  --> $DIR/duplicate.rs:93:40
    |
 LL | type ETAI5 = impl Iterator<Item: Copy, Item: Copy>;
    |                            ----------  ^^^^^^^^^^ re-bound here
@@ -392,7 +312,7 @@ LL | type ETAI5 = impl Iterator<Item: Copy, Item: Copy>;
    |                            `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:116:43
+  --> $DIR/duplicate.rs:95:43
    |
 LL | type ETAI6 = impl Iterator<Item: 'static, Item: 'static>;
    |                            -------------  ^^^^^^^^^^^^^ re-bound here
@@ -400,7 +320,7 @@ LL | type ETAI6 = impl Iterator<Item: 'static, Item: 'static>;
    |                            `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:119:36
+  --> $DIR/duplicate.rs:98:36
    |
 LL | trait TRI1<T: Iterator<Item: Copy, Item: Send>> {}
    |                        ----------  ^^^^^^^^^^ re-bound here
@@ -408,7 +328,7 @@ LL | trait TRI1<T: Iterator<Item: Copy, Item: Send>> {}
    |                        `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:121:36
+  --> $DIR/duplicate.rs:100:36
    |
 LL | trait TRI2<T: Iterator<Item: Copy, Item: Copy>> {}
    |                        ----------  ^^^^^^^^^^ re-bound here
@@ -416,7 +336,7 @@ LL | trait TRI2<T: Iterator<Item: Copy, Item: Copy>> {}
    |                        `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:123:39
+  --> $DIR/duplicate.rs:102:39
    |
 LL | trait TRI3<T: Iterator<Item: 'static, Item: 'static>> {}
    |                        -------------  ^^^^^^^^^^^^^ re-bound here
@@ -424,7 +344,7 @@ LL | trait TRI3<T: Iterator<Item: 'static, Item: 'static>> {}
    |                        `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:125:34
+  --> $DIR/duplicate.rs:104:34
    |
 LL | trait TRS1: Iterator<Item: Copy, Item: Send> {}
    |                      ----------  ^^^^^^^^^^ re-bound here
@@ -432,7 +352,7 @@ LL | trait TRS1: Iterator<Item: Copy, Item: Send> {}
    |                      `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:127:34
+  --> $DIR/duplicate.rs:106:34
    |
 LL | trait TRS2: Iterator<Item: Copy, Item: Copy> {}
    |                      ----------  ^^^^^^^^^^ re-bound here
@@ -440,7 +360,7 @@ LL | trait TRS2: Iterator<Item: Copy, Item: Copy> {}
    |                      `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:129:37
+  --> $DIR/duplicate.rs:108:37
    |
 LL | trait TRS3: Iterator<Item: 'static, Item: 'static> {}
    |                      -------------  ^^^^^^^^^^^^^ re-bound here
@@ -448,7 +368,7 @@ LL | trait TRS3: Iterator<Item: 'static, Item: 'static> {}
    |                      `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:131:45
+  --> $DIR/duplicate.rs:110:45
    |
 LL | trait TRW1<T> where T: Iterator<Item: Copy, Item: Send> {}
    |                                 ----------  ^^^^^^^^^^ re-bound here
@@ -456,7 +376,7 @@ LL | trait TRW1<T> where T: Iterator<Item: Copy, Item: Send> {}
    |                                 `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:133:45
+  --> $DIR/duplicate.rs:112:45
    |
 LL | trait TRW2<T> where T: Iterator<Item: Copy, Item: Copy> {}
    |                                 ----------  ^^^^^^^^^^ re-bound here
@@ -464,7 +384,7 @@ LL | trait TRW2<T> where T: Iterator<Item: Copy, Item: Copy> {}
    |                                 `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:135:48
+  --> $DIR/duplicate.rs:114:48
    |
 LL | trait TRW3<T> where T: Iterator<Item: 'static, Item: 'static> {}
    |                                 -------------  ^^^^^^^^^^^^^ re-bound here
@@ -472,7 +392,7 @@ LL | trait TRW3<T> where T: Iterator<Item: 'static, Item: 'static> {}
    |                                 `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:137:46
+  --> $DIR/duplicate.rs:116:46
    |
 LL | trait TRSW1 where Self: Iterator<Item: Copy, Item: Send> {}
    |                                  ----------  ^^^^^^^^^^ re-bound here
@@ -480,7 +400,7 @@ LL | trait TRSW1 where Self: Iterator<Item: Copy, Item: Send> {}
    |                                  `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:137:46
+  --> $DIR/duplicate.rs:116:46
    |
 LL | trait TRSW1 where Self: Iterator<Item: Copy, Item: Send> {}
    |                                  ----------  ^^^^^^^^^^ re-bound here
@@ -488,7 +408,7 @@ LL | trait TRSW1 where Self: Iterator<Item: Copy, Item: Send> {}
    |                                  `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:140:46
+  --> $DIR/duplicate.rs:119:46
    |
 LL | trait TRSW2 where Self: Iterator<Item: Copy, Item: Copy> {}
    |                                  ----------  ^^^^^^^^^^ re-bound here
@@ -496,7 +416,7 @@ LL | trait TRSW2 where Self: Iterator<Item: Copy, Item: Copy> {}
    |                                  `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:140:46
+  --> $DIR/duplicate.rs:119:46
    |
 LL | trait TRSW2 where Self: Iterator<Item: Copy, Item: Copy> {}
    |                                  ----------  ^^^^^^^^^^ re-bound here
@@ -504,7 +424,7 @@ LL | trait TRSW2 where Self: Iterator<Item: Copy, Item: Copy> {}
    |                                  `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:143:49
+  --> $DIR/duplicate.rs:122:49
    |
 LL | trait TRSW3 where Self: Iterator<Item: 'static, Item: 'static> {}
    |                                  -------------  ^^^^^^^^^^^^^ re-bound here
@@ -512,7 +432,7 @@ LL | trait TRSW3 where Self: Iterator<Item: 'static, Item: 'static> {}
    |                                  `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:143:49
+  --> $DIR/duplicate.rs:122:49
    |
 LL | trait TRSW3 where Self: Iterator<Item: 'static, Item: 'static> {}
    |                                  -------------  ^^^^^^^^^^^^^ re-bound here
@@ -520,7 +440,7 @@ LL | trait TRSW3 where Self: Iterator<Item: 'static, Item: 'static> {}
    |                                  `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:153:40
+  --> $DIR/duplicate.rs:132:40
    |
 LL | type TADyn1 = dyn Iterator<Item: Copy, Item: Send>;
    |                            ----------  ^^^^^^^^^^ re-bound here
@@ -528,7 +448,7 @@ LL | type TADyn1 = dyn Iterator<Item: Copy, Item: Send>;
    |                            `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:155:44
+  --> $DIR/duplicate.rs:134:44
    |
 LL | type TADyn2 = Box<dyn Iterator<Item: Copy, Item: Copy>>;
    |                                ----------  ^^^^^^^^^^ re-bound here
@@ -536,7 +456,7 @@ LL | type TADyn2 = Box<dyn Iterator<Item: Copy, Item: Copy>>;
    |                                `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:157:43
+  --> $DIR/duplicate.rs:136:43
    |
 LL | type TADyn3 = dyn Iterator<Item: 'static, Item: 'static>;
    |                            -------------  ^^^^^^^^^^^^^ re-bound here
@@ -544,7 +464,7 @@ LL | type TADyn3 = dyn Iterator<Item: 'static, Item: 'static>;
    |                            `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:146:43
+  --> $DIR/duplicate.rs:125:43
    |
 LL | trait TRA1 { type A: Iterator<Item: Copy, Item: Send>; }
    |                               ----------  ^^^^^^^^^^ re-bound here
@@ -552,7 +472,7 @@ LL | trait TRA1 { type A: Iterator<Item: Copy, Item: Send>; }
    |                               `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:148:43
+  --> $DIR/duplicate.rs:127:43
    |
 LL | trait TRA2 { type A: Iterator<Item: Copy, Item: Copy>; }
    |                               ----------  ^^^^^^^^^^ re-bound here
@@ -560,13 +480,13 @@ LL | trait TRA2 { type A: Iterator<Item: Copy, Item: Copy>; }
    |                               `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:150:46
+  --> $DIR/duplicate.rs:129:46
    |
 LL | trait TRA3 { type A: Iterator<Item: 'static, Item: 'static>; }
    |                               -------------  ^^^^^^^^^^^^^ re-bound here
    |                               |
    |                               `Item` bound here first
 
-error: aborting due to 69 previous errors; 2 warnings emitted
+error: aborting due to 60 previous errors; 1 warning emitted
 
 For more information about this error, try `rustc --explain E0719`.
index 500e527a0188afcfb3911bbaa4d97f27e8ec53f9..06bfac588de0060374fc515e9a26b7860c3d0938 100644 (file)
@@ -1,14 +1,5 @@
-warning: the feature `impl_trait_in_bindings` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/duplicate.rs:6:12
-   |
-LL | #![feature(impl_trait_in_bindings)]
-   |            ^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(incomplete_features)]` on by default
-   = note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
-
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:11:36
+  --> $DIR/duplicate.rs:10:36
    |
 LL | struct SI1<T: Iterator<Item: Copy, Item: Send>> { f: T }
    |                        ----------  ^^^^^^^^^^ re-bound here
@@ -16,7 +7,7 @@ LL | struct SI1<T: Iterator<Item: Copy, Item: Send>> { f: T }
    |                        `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:13:36
+  --> $DIR/duplicate.rs:12:36
    |
 LL | struct SI2<T: Iterator<Item: Copy, Item: Copy>> { f: T }
    |                        ----------  ^^^^^^^^^^ re-bound here
@@ -24,7 +15,7 @@ LL | struct SI2<T: Iterator<Item: Copy, Item: Copy>> { f: T }
    |                        `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:15:39
+  --> $DIR/duplicate.rs:14:39
    |
 LL | struct SI3<T: Iterator<Item: 'static, Item: 'static>> { f: T }
    |                        -------------  ^^^^^^^^^^^^^ re-bound here
@@ -32,7 +23,7 @@ LL | struct SI3<T: Iterator<Item: 'static, Item: 'static>> { f: T }
    |                        `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:17:45
+  --> $DIR/duplicate.rs:16:45
    |
 LL | struct SW1<T> where T: Iterator<Item: Copy, Item: Send> { f: T }
    |                                 ----------  ^^^^^^^^^^ re-bound here
@@ -40,7 +31,7 @@ LL | struct SW1<T> where T: Iterator<Item: Copy, Item: Send> { f: T }
    |                                 `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:19:45
+  --> $DIR/duplicate.rs:18:45
    |
 LL | struct SW2<T> where T: Iterator<Item: Copy, Item: Copy> { f: T }
    |                                 ----------  ^^^^^^^^^^ re-bound here
@@ -48,7 +39,7 @@ LL | struct SW2<T> where T: Iterator<Item: Copy, Item: Copy> { f: T }
    |                                 `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:21:48
+  --> $DIR/duplicate.rs:20:48
    |
 LL | struct SW3<T> where T: Iterator<Item: 'static, Item: 'static> { f: T }
    |                                 -------------  ^^^^^^^^^^^^^ re-bound here
@@ -56,7 +47,7 @@ LL | struct SW3<T> where T: Iterator<Item: 'static, Item: 'static> { f: T }
    |                                 `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:24:34
+  --> $DIR/duplicate.rs:23:34
    |
 LL | enum EI1<T: Iterator<Item: Copy, Item: Send>> { V(T) }
    |                      ----------  ^^^^^^^^^^ re-bound here
@@ -64,7 +55,7 @@ LL | enum EI1<T: Iterator<Item: Copy, Item: Send>> { V(T) }
    |                      `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:26:34
+  --> $DIR/duplicate.rs:25:34
    |
 LL | enum EI2<T: Iterator<Item: Copy, Item: Copy>> { V(T) }
    |                      ----------  ^^^^^^^^^^ re-bound here
@@ -72,7 +63,7 @@ LL | enum EI2<T: Iterator<Item: Copy, Item: Copy>> { V(T) }
    |                      `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:28:37
+  --> $DIR/duplicate.rs:27:37
    |
 LL | enum EI3<T: Iterator<Item: 'static, Item: 'static>> { V(T) }
    |                      -------------  ^^^^^^^^^^^^^ re-bound here
@@ -80,7 +71,7 @@ LL | enum EI3<T: Iterator<Item: 'static, Item: 'static>> { V(T) }
    |                      `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:30:43
+  --> $DIR/duplicate.rs:29:43
    |
 LL | enum EW1<T> where T: Iterator<Item: Copy, Item: Send> { V(T) }
    |                               ----------  ^^^^^^^^^^ re-bound here
@@ -88,7 +79,7 @@ LL | enum EW1<T> where T: Iterator<Item: Copy, Item: Send> { V(T) }
    |                               `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:32:43
+  --> $DIR/duplicate.rs:31:43
    |
 LL | enum EW2<T> where T: Iterator<Item: Copy, Item: Copy> { V(T) }
    |                               ----------  ^^^^^^^^^^ re-bound here
@@ -96,7 +87,7 @@ LL | enum EW2<T> where T: Iterator<Item: Copy, Item: Copy> { V(T) }
    |                               `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:34:46
+  --> $DIR/duplicate.rs:33:46
    |
 LL | enum EW3<T> where T: Iterator<Item: 'static, Item: 'static> { V(T) }
    |                               -------------  ^^^^^^^^^^^^^ re-bound here
@@ -104,7 +95,7 @@ LL | enum EW3<T> where T: Iterator<Item: 'static, Item: 'static> { V(T) }
    |                               `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:37:35
+  --> $DIR/duplicate.rs:36:35
    |
 LL | union UI1<T: Iterator<Item: Copy, Item: Send>> { f: T }
    |                       ----------  ^^^^^^^^^^ re-bound here
@@ -112,7 +103,7 @@ LL | union UI1<T: Iterator<Item: Copy, Item: Send>> { f: T }
    |                       `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:39:35
+  --> $DIR/duplicate.rs:38:35
    |
 LL | union UI2<T: Iterator<Item: Copy, Item: Copy>> { f: T }
    |                       ----------  ^^^^^^^^^^ re-bound here
@@ -120,7 +111,7 @@ LL | union UI2<T: Iterator<Item: Copy, Item: Copy>> { f: T }
    |                       `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:41:38
+  --> $DIR/duplicate.rs:40:38
    |
 LL | union UI3<T: Iterator<Item: 'static, Item: 'static>> { f: T }
    |                       -------------  ^^^^^^^^^^^^^ re-bound here
@@ -128,7 +119,7 @@ LL | union UI3<T: Iterator<Item: 'static, Item: 'static>> { f: T }
    |                       `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:43:44
+  --> $DIR/duplicate.rs:42:44
    |
 LL | union UW1<T> where T: Iterator<Item: Copy, Item: Send> { f: T }
    |                                ----------  ^^^^^^^^^^ re-bound here
@@ -136,7 +127,7 @@ LL | union UW1<T> where T: Iterator<Item: Copy, Item: Send> { f: T }
    |                                `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:45:44
+  --> $DIR/duplicate.rs:44:44
    |
 LL | union UW2<T> where T: Iterator<Item: Copy, Item: Copy> { f: T }
    |                                ----------  ^^^^^^^^^^ re-bound here
@@ -144,7 +135,7 @@ LL | union UW2<T> where T: Iterator<Item: Copy, Item: Copy> { f: T }
    |                                `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:47:47
+  --> $DIR/duplicate.rs:46:47
    |
 LL | union UW3<T> where T: Iterator<Item: 'static, Item: 'static> { f: T }
    |                                -------------  ^^^^^^^^^^^^^ re-bound here
@@ -152,7 +143,7 @@ LL | union UW3<T> where T: Iterator<Item: 'static, Item: 'static> { f: T }
    |                                `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:50:32
+  --> $DIR/duplicate.rs:49:32
    |
 LL | fn FI1<T: Iterator<Item: Copy, Item: Send>>() {}
    |                    ----------  ^^^^^^^^^^ re-bound here
@@ -160,7 +151,7 @@ LL | fn FI1<T: Iterator<Item: Copy, Item: Send>>() {}
    |                    `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:52:32
+  --> $DIR/duplicate.rs:51:32
    |
 LL | fn FI2<T: Iterator<Item: Copy, Item: Copy>>() {}
    |                    ----------  ^^^^^^^^^^ re-bound here
@@ -168,7 +159,7 @@ LL | fn FI2<T: Iterator<Item: Copy, Item: Copy>>() {}
    |                    `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:54:35
+  --> $DIR/duplicate.rs:53:35
    |
 LL | fn FI3<T: Iterator<Item: 'static, Item: 'static>>() {}
    |                    -------------  ^^^^^^^^^^^^^ re-bound here
@@ -176,7 +167,7 @@ LL | fn FI3<T: Iterator<Item: 'static, Item: 'static>>() {}
    |                    `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:56:43
+  --> $DIR/duplicate.rs:55:43
    |
 LL | fn FW1<T>() where T: Iterator<Item: Copy, Item: Send> {}
    |                               ----------  ^^^^^^^^^^ re-bound here
@@ -184,7 +175,7 @@ LL | fn FW1<T>() where T: Iterator<Item: Copy, Item: Send> {}
    |                               `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:58:43
+  --> $DIR/duplicate.rs:57:43
    |
 LL | fn FW2<T>() where T: Iterator<Item: Copy, Item: Copy> {}
    |                               ----------  ^^^^^^^^^^ re-bound here
@@ -192,7 +183,7 @@ LL | fn FW2<T>() where T: Iterator<Item: Copy, Item: Copy> {}
    |                               `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:60:46
+  --> $DIR/duplicate.rs:59:46
    |
 LL | fn FW3<T>() where T: Iterator<Item: 'static, Item: 'static> {}
    |                               -------------  ^^^^^^^^^^^^^ re-bound here
@@ -200,7 +191,7 @@ LL | fn FW3<T>() where T: Iterator<Item: 'static, Item: 'static> {}
    |                               `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:66:40
+  --> $DIR/duplicate.rs:65:40
    |
 LL | fn FAPIT1(_: impl Iterator<Item: Copy, Item: Send>) {}
    |                            ----------  ^^^^^^^^^^ re-bound here
@@ -208,7 +199,7 @@ LL | fn FAPIT1(_: impl Iterator<Item: Copy, Item: Send>) {}
    |                            `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:68:40
+  --> $DIR/duplicate.rs:67:40
    |
 LL | fn FAPIT2(_: impl Iterator<Item: Copy, Item: Copy>) {}
    |                            ----------  ^^^^^^^^^^ re-bound here
@@ -216,7 +207,7 @@ LL | fn FAPIT2(_: impl Iterator<Item: Copy, Item: Copy>) {}
    |                            `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:70:43
+  --> $DIR/duplicate.rs:69:43
    |
 LL | fn FAPIT3(_: impl Iterator<Item: 'static, Item: 'static>) {}
    |                            -------------  ^^^^^^^^^^^^^ re-bound here
@@ -224,79 +215,7 @@ LL | fn FAPIT3(_: impl Iterator<Item: 'static, Item: 'static>) {}
    |                            `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:73:39
-   |
-LL | const CIT1: impl Iterator<Item: Copy, Item: Send> = iter::empty();
-   |                           ----------  ^^^^^^^^^^ re-bound here
-   |                           |
-   |                           `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:75:39
-   |
-LL | const CIT2: impl Iterator<Item: Copy, Item: Copy> = iter::empty();
-   |                           ----------  ^^^^^^^^^^ re-bound here
-   |                           |
-   |                           `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:77:42
-   |
-LL | const CIT3: impl Iterator<Item: 'static, Item: 'static> = iter::empty();
-   |                           -------------  ^^^^^^^^^^^^^ re-bound here
-   |                           |
-   |                           `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:79:40
-   |
-LL | static SIT1: impl Iterator<Item: Copy, Item: Send> = iter::empty();
-   |                            ----------  ^^^^^^^^^^ re-bound here
-   |                            |
-   |                            `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:81:40
-   |
-LL | static SIT2: impl Iterator<Item: Copy, Item: Copy> = iter::empty();
-   |                            ----------  ^^^^^^^^^^ re-bound here
-   |                            |
-   |                            `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:83:43
-   |
-LL | static SIT3: impl Iterator<Item: 'static, Item: 'static> = iter::empty();
-   |                            -------------  ^^^^^^^^^^^^^ re-bound here
-   |                            |
-   |                            `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:86:46
-   |
-LL | fn lit1() { let _: impl Iterator<Item: Copy, Item: Send> = iter::empty(); }
-   |                                  ----------  ^^^^^^^^^^ re-bound here
-   |                                  |
-   |                                  `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:88:46
-   |
-LL | fn lit2() { let _: impl Iterator<Item: Copy, Item: Copy> = iter::empty(); }
-   |                                  ----------  ^^^^^^^^^^ re-bound here
-   |                                  |
-   |                                  `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:90:49
-   |
-LL | fn lit3() { let _: impl Iterator<Item: 'static, Item: 'static> = iter::empty(); }
-   |                                  -------------  ^^^^^^^^^^^^^ re-bound here
-   |                                  |
-   |                                  `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:93:35
+  --> $DIR/duplicate.rs:72:35
    |
 LL | type TAI1<T: Iterator<Item: Copy, Item: Send>> = T;
    |                       ----------  ^^^^^^^^^^ re-bound here
@@ -304,7 +223,7 @@ LL | type TAI1<T: Iterator<Item: Copy, Item: Send>> = T;
    |                       `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:95:35
+  --> $DIR/duplicate.rs:74:35
    |
 LL | type TAI2<T: Iterator<Item: Copy, Item: Copy>> = T;
    |                       ----------  ^^^^^^^^^^ re-bound here
@@ -312,7 +231,7 @@ LL | type TAI2<T: Iterator<Item: Copy, Item: Copy>> = T;
    |                       `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:97:38
+  --> $DIR/duplicate.rs:76:38
    |
 LL | type TAI3<T: Iterator<Item: 'static, Item: 'static>> = T;
    |                       -------------  ^^^^^^^^^^^^^ re-bound here
@@ -320,7 +239,7 @@ LL | type TAI3<T: Iterator<Item: 'static, Item: 'static>> = T;
    |                       `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:99:44
+  --> $DIR/duplicate.rs:78:44
    |
 LL | type TAW1<T> where T: Iterator<Item: Copy, Item: Send> = T;
    |                                ----------  ^^^^^^^^^^ re-bound here
@@ -328,7 +247,7 @@ LL | type TAW1<T> where T: Iterator<Item: Copy, Item: Send> = T;
    |                                `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:101:44
+  --> $DIR/duplicate.rs:80:44
    |
 LL | type TAW2<T> where T: Iterator<Item: Copy, Item: Copy> = T;
    |                                ----------  ^^^^^^^^^^ re-bound here
@@ -336,7 +255,7 @@ LL | type TAW2<T> where T: Iterator<Item: Copy, Item: Copy> = T;
    |                                `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:103:47
+  --> $DIR/duplicate.rs:82:47
    |
 LL | type TAW3<T> where T: Iterator<Item: 'static, Item: 'static> = T;
    |                                -------------  ^^^^^^^^^^^^^ re-bound here
@@ -344,7 +263,7 @@ LL | type TAW3<T> where T: Iterator<Item: 'static, Item: 'static> = T;
    |                                `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:106:36
+  --> $DIR/duplicate.rs:85:36
    |
 LL | type ETAI1<T: Iterator<Item: Copy, Item: Send>> = impl Copy;
    |                        ----------  ^^^^^^^^^^ re-bound here
@@ -352,7 +271,7 @@ LL | type ETAI1<T: Iterator<Item: Copy, Item: Send>> = impl Copy;
    |                        `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:108:36
+  --> $DIR/duplicate.rs:87:36
    |
 LL | type ETAI2<T: Iterator<Item: Copy, Item: Copy>> = impl Copy;
    |                        ----------  ^^^^^^^^^^ re-bound here
@@ -360,7 +279,7 @@ LL | type ETAI2<T: Iterator<Item: Copy, Item: Copy>> = impl Copy;
    |                        `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:110:39
+  --> $DIR/duplicate.rs:89:39
    |
 LL | type ETAI3<T: Iterator<Item: 'static, Item: 'static>> = impl Copy;
    |                        -------------  ^^^^^^^^^^^^^ re-bound here
@@ -368,7 +287,7 @@ LL | type ETAI3<T: Iterator<Item: 'static, Item: 'static>> = impl Copy;
    |                        `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:112:40
+  --> $DIR/duplicate.rs:91:40
    |
 LL | type ETAI4 = impl Iterator<Item: Copy, Item: Send>;
    |                            ----------  ^^^^^^^^^^ re-bound here
@@ -376,7 +295,7 @@ LL | type ETAI4 = impl Iterator<Item: Copy, Item: Send>;
    |                            `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:114:40
+  --> $DIR/duplicate.rs:93:40
    |
 LL | type ETAI5 = impl Iterator<Item: Copy, Item: Copy>;
    |                            ----------  ^^^^^^^^^^ re-bound here
@@ -384,7 +303,7 @@ LL | type ETAI5 = impl Iterator<Item: Copy, Item: Copy>;
    |                            `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:116:43
+  --> $DIR/duplicate.rs:95:43
    |
 LL | type ETAI6 = impl Iterator<Item: 'static, Item: 'static>;
    |                            -------------  ^^^^^^^^^^^^^ re-bound here
@@ -392,7 +311,7 @@ LL | type ETAI6 = impl Iterator<Item: 'static, Item: 'static>;
    |                            `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:119:36
+  --> $DIR/duplicate.rs:98:36
    |
 LL | trait TRI1<T: Iterator<Item: Copy, Item: Send>> {}
    |                        ----------  ^^^^^^^^^^ re-bound here
@@ -400,7 +319,7 @@ LL | trait TRI1<T: Iterator<Item: Copy, Item: Send>> {}
    |                        `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:121:36
+  --> $DIR/duplicate.rs:100:36
    |
 LL | trait TRI2<T: Iterator<Item: Copy, Item: Copy>> {}
    |                        ----------  ^^^^^^^^^^ re-bound here
@@ -408,7 +327,7 @@ LL | trait TRI2<T: Iterator<Item: Copy, Item: Copy>> {}
    |                        `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:123:39
+  --> $DIR/duplicate.rs:102:39
    |
 LL | trait TRI3<T: Iterator<Item: 'static, Item: 'static>> {}
    |                        -------------  ^^^^^^^^^^^^^ re-bound here
@@ -416,7 +335,7 @@ LL | trait TRI3<T: Iterator<Item: 'static, Item: 'static>> {}
    |                        `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:125:34
+  --> $DIR/duplicate.rs:104:34
    |
 LL | trait TRS1: Iterator<Item: Copy, Item: Send> {}
    |                      ----------  ^^^^^^^^^^ re-bound here
@@ -424,7 +343,7 @@ LL | trait TRS1: Iterator<Item: Copy, Item: Send> {}
    |                      `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:127:34
+  --> $DIR/duplicate.rs:106:34
    |
 LL | trait TRS2: Iterator<Item: Copy, Item: Copy> {}
    |                      ----------  ^^^^^^^^^^ re-bound here
@@ -432,7 +351,7 @@ LL | trait TRS2: Iterator<Item: Copy, Item: Copy> {}
    |                      `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:129:37
+  --> $DIR/duplicate.rs:108:37
    |
 LL | trait TRS3: Iterator<Item: 'static, Item: 'static> {}
    |                      -------------  ^^^^^^^^^^^^^ re-bound here
@@ -440,7 +359,7 @@ LL | trait TRS3: Iterator<Item: 'static, Item: 'static> {}
    |                      `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:131:45
+  --> $DIR/duplicate.rs:110:45
    |
 LL | trait TRW1<T> where T: Iterator<Item: Copy, Item: Send> {}
    |                                 ----------  ^^^^^^^^^^ re-bound here
@@ -448,7 +367,7 @@ LL | trait TRW1<T> where T: Iterator<Item: Copy, Item: Send> {}
    |                                 `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:133:45
+  --> $DIR/duplicate.rs:112:45
    |
 LL | trait TRW2<T> where T: Iterator<Item: Copy, Item: Copy> {}
    |                                 ----------  ^^^^^^^^^^ re-bound here
@@ -456,7 +375,7 @@ LL | trait TRW2<T> where T: Iterator<Item: Copy, Item: Copy> {}
    |                                 `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:135:48
+  --> $DIR/duplicate.rs:114:48
    |
 LL | trait TRW3<T> where T: Iterator<Item: 'static, Item: 'static> {}
    |                                 -------------  ^^^^^^^^^^^^^ re-bound here
@@ -464,7 +383,7 @@ LL | trait TRW3<T> where T: Iterator<Item: 'static, Item: 'static> {}
    |                                 `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:137:46
+  --> $DIR/duplicate.rs:116:46
    |
 LL | trait TRSW1 where Self: Iterator<Item: Copy, Item: Send> {}
    |                                  ----------  ^^^^^^^^^^ re-bound here
@@ -472,7 +391,7 @@ LL | trait TRSW1 where Self: Iterator<Item: Copy, Item: Send> {}
    |                                  `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:137:46
+  --> $DIR/duplicate.rs:116:46
    |
 LL | trait TRSW1 where Self: Iterator<Item: Copy, Item: Send> {}
    |                                  ----------  ^^^^^^^^^^ re-bound here
@@ -480,7 +399,7 @@ LL | trait TRSW1 where Self: Iterator<Item: Copy, Item: Send> {}
    |                                  `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:140:46
+  --> $DIR/duplicate.rs:119:46
    |
 LL | trait TRSW2 where Self: Iterator<Item: Copy, Item: Copy> {}
    |                                  ----------  ^^^^^^^^^^ re-bound here
@@ -488,7 +407,7 @@ LL | trait TRSW2 where Self: Iterator<Item: Copy, Item: Copy> {}
    |                                  `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:140:46
+  --> $DIR/duplicate.rs:119:46
    |
 LL | trait TRSW2 where Self: Iterator<Item: Copy, Item: Copy> {}
    |                                  ----------  ^^^^^^^^^^ re-bound here
@@ -496,7 +415,7 @@ LL | trait TRSW2 where Self: Iterator<Item: Copy, Item: Copy> {}
    |                                  `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:143:49
+  --> $DIR/duplicate.rs:122:49
    |
 LL | trait TRSW3 where Self: Iterator<Item: 'static, Item: 'static> {}
    |                                  -------------  ^^^^^^^^^^^^^ re-bound here
@@ -504,7 +423,7 @@ LL | trait TRSW3 where Self: Iterator<Item: 'static, Item: 'static> {}
    |                                  `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:143:49
+  --> $DIR/duplicate.rs:122:49
    |
 LL | trait TRSW3 where Self: Iterator<Item: 'static, Item: 'static> {}
    |                                  -------------  ^^^^^^^^^^^^^ re-bound here
@@ -512,7 +431,7 @@ LL | trait TRSW3 where Self: Iterator<Item: 'static, Item: 'static> {}
    |                                  `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:153:40
+  --> $DIR/duplicate.rs:132:40
    |
 LL | type TADyn1 = dyn Iterator<Item: Copy, Item: Send>;
    |                            ----------  ^^^^^^^^^^ re-bound here
@@ -520,7 +439,7 @@ LL | type TADyn1 = dyn Iterator<Item: Copy, Item: Send>;
    |                            `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:155:44
+  --> $DIR/duplicate.rs:134:44
    |
 LL | type TADyn2 = Box<dyn Iterator<Item: Copy, Item: Copy>>;
    |                                ----------  ^^^^^^^^^^ re-bound here
@@ -528,7 +447,7 @@ LL | type TADyn2 = Box<dyn Iterator<Item: Copy, Item: Copy>>;
    |                                `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:157:43
+  --> $DIR/duplicate.rs:136:43
    |
 LL | type TADyn3 = dyn Iterator<Item: 'static, Item: 'static>;
    |                            -------------  ^^^^^^^^^^^^^ re-bound here
@@ -536,7 +455,7 @@ LL | type TADyn3 = dyn Iterator<Item: 'static, Item: 'static>;
    |                            `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:146:43
+  --> $DIR/duplicate.rs:125:43
    |
 LL | trait TRA1 { type A: Iterator<Item: Copy, Item: Send>; }
    |                               ----------  ^^^^^^^^^^ re-bound here
@@ -544,7 +463,7 @@ LL | trait TRA1 { type A: Iterator<Item: Copy, Item: Send>; }
    |                               `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:148:43
+  --> $DIR/duplicate.rs:127:43
    |
 LL | trait TRA2 { type A: Iterator<Item: Copy, Item: Copy>; }
    |                               ----------  ^^^^^^^^^^ re-bound here
@@ -552,13 +471,13 @@ LL | trait TRA2 { type A: Iterator<Item: Copy, Item: Copy>; }
    |                               `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
-  --> $DIR/duplicate.rs:150:46
+  --> $DIR/duplicate.rs:129:46
    |
 LL | trait TRA3 { type A: Iterator<Item: 'static, Item: 'static>; }
    |                               -------------  ^^^^^^^^^^^^^ re-bound here
    |                               |
    |                               `Item` bound here first
 
-error: aborting due to 69 previous errors; 1 warning emitted
+error: aborting due to 60 previous errors
 
 For more information about this error, try `rustc --explain E0719`.
index c3319a7050d5d0d20f3d01ae712c71315900bfd7..0d7804ef1a7d5feb499b3f52cb99a04138588ccc 100644 (file)
@@ -3,7 +3,6 @@
 #![feature(min_type_alias_impl_trait)]
 #![cfg_attr(full_tait, feature(type_alias_impl_trait))]
 //[full_tait]~^ WARN incomplete
-#![feature(impl_trait_in_bindings)] //~ WARN the feature `impl_trait_in_bindings` is incomplete
 #![feature(untagged_unions)]
 
 use std::iter;
@@ -70,26 +69,6 @@ fn FAPIT2(_: impl Iterator<Item: Copy, Item: Copy>) {}
 fn FAPIT3(_: impl Iterator<Item: 'static, Item: 'static>) {}
 //~^ ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719]
 
-const CIT1: impl Iterator<Item: Copy, Item: Send> = iter::empty();
-//~^ ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719]
-const CIT2: impl Iterator<Item: Copy, Item: Copy> = iter::empty();
-//~^ ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719]
-const CIT3: impl Iterator<Item: 'static, Item: 'static> = iter::empty();
-//~^ ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719]
-static SIT1: impl Iterator<Item: Copy, Item: Send> = iter::empty();
-//~^ ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719]
-static SIT2: impl Iterator<Item: Copy, Item: Copy> = iter::empty();
-//~^ ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719]
-static SIT3: impl Iterator<Item: 'static, Item: 'static> = iter::empty();
-//~^ ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719]
-
-fn lit1() { let _: impl Iterator<Item: Copy, Item: Send> = iter::empty(); }
-//~^ ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719]
-fn lit2() { let _: impl Iterator<Item: Copy, Item: Copy> = iter::empty(); }
-//~^ ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719]
-fn lit3() { let _: impl Iterator<Item: 'static, Item: 'static> = iter::empty(); }
-//~^ ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719]
-
 type TAI1<T: Iterator<Item: Copy, Item: Send>> = T;
 //~^ ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719]
 type TAI2<T: Iterator<Item: Copy, Item: Copy>> = T;
diff --git a/src/test/ui/associated-type-bounds/dyn-lcsit.rs b/src/test/ui/associated-type-bounds/dyn-lcsit.rs
deleted file mode 100644 (file)
index b7869e2..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-// run-pass
-
-#![feature(associated_type_bounds)]
-#![feature(impl_trait_in_bindings)]
-//~^ WARNING `impl_trait_in_bindings` is incomplete
-#![allow(non_upper_case_globals)]
-
-use std::ops::Add;
-
-trait Tr1 { type As1; fn mk(&self) -> Self::As1; }
-trait Tr2<'a> { fn tr2(self) -> &'a Self; }
-
-fn assert_copy<T: Copy>(x: T) { let _x = x; let _x = x; }
-fn assert_static<T: 'static>(_: T) {}
-fn assert_forall_tr2<T: for<'a> Tr2<'a>>(_: T) {}
-
-#[derive(Copy, Clone)]
-struct S1;
-#[derive(Copy, Clone)]
-struct S2;
-impl Tr1 for S1 { type As1 = S2; fn mk(&self) -> Self::As1 { S2 } }
-
-const cdef_et1: &dyn Tr1<As1: Copy> = &S1;
-const sdef_et1: &dyn Tr1<As1: Copy> = &S1;
-pub fn use_et1() { assert_copy(cdef_et1.mk()); assert_copy(sdef_et1.mk()); }
-
-const cdef_et2: &(dyn Tr1<As1: 'static> + Sync) = &S1;
-static sdef_et2: &(dyn Tr1<As1: 'static> + Sync) = &S1;
-pub fn use_et2() { assert_static(cdef_et2.mk()); assert_static(sdef_et2.mk()); }
-
-const cdef_et3: &dyn Tr1<As1: Clone + Iterator<Item: Add<u8, Output: Into<u8>>>> = {
-    struct A;
-    impl Tr1 for A {
-        type As1 = core::ops::Range<u8>;
-        fn mk(&self) -> Self::As1 { 0..10 }
-    }
-    &A
-};
-pub fn use_et3() {
-    let _0 = cdef_et3.mk().clone();
-    let mut s = 0u8;
-    for _1 in _0 {
-        let _2 = _1 + 1u8;
-        s += _2.into();
-    }
-    assert_eq!(s, (0..10).map(|x| x + 1).sum());
-}
-
-const cdef_et4: &(dyn Tr1<As1: for<'a> Tr2<'a>> + Sync) = {
-    #[derive(Copy, Clone)]
-    struct A;
-    impl Tr1 for A {
-        type As1 = A;
-        fn mk(&self) -> A { A }
-    }
-    impl<'a> Tr2<'a> for A {
-        fn tr2(self) -> &'a Self { &A }
-    }
-    &A
-};
-static sdef_et4: &(dyn Tr1<As1: for<'a> Tr2<'a>> + Sync) = cdef_et4;
-pub fn use_et4() { assert_forall_tr2(cdef_et4.mk()); assert_forall_tr2(sdef_et4.mk()); }
-
-fn main() {
-    let _ = use_et1();
-    let _ = use_et2();
-    let _ = use_et3();
-    let _ = use_et4();
-}
diff --git a/src/test/ui/associated-type-bounds/dyn-lcsit.stderr b/src/test/ui/associated-type-bounds/dyn-lcsit.stderr
deleted file mode 100644 (file)
index 3637f95..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-warning: the feature `impl_trait_in_bindings` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/dyn-lcsit.rs:4:12
-   |
-LL | #![feature(impl_trait_in_bindings)]
-   |            ^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(incomplete_features)]` on by default
-   = note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
-
-warning: 1 warning emitted
-
diff --git a/src/test/ui/associated-type-bounds/lcsit.rs b/src/test/ui/associated-type-bounds/lcsit.rs
deleted file mode 100644 (file)
index 5364f25..0000000
+++ /dev/null
@@ -1,78 +0,0 @@
-// run-pass
-
-#![feature(associated_type_bounds)]
-#![feature(impl_trait_in_bindings)]
-//~^ WARNING `impl_trait_in_bindings` is incomplete
-#![allow(non_upper_case_globals)]
-
-use std::ops::Add;
-
-trait Tr1 { type As1; fn mk(&self) -> Self::As1; }
-trait Tr2<'a> { fn tr2(self) -> &'a Self; }
-
-fn assert_copy<T: Copy>(x: T) { let _x = x; let _x = x; }
-fn assert_static<T: 'static>(_: T) {}
-fn assert_forall_tr2<T: for<'a> Tr2<'a>>(_: T) {}
-
-#[derive(Copy, Clone)]
-struct S1;
-#[derive(Copy, Clone)]
-struct S2;
-impl Tr1 for S1 { type As1 = S2; fn mk(&self) -> Self::As1 { S2 } }
-
-const cdef_et1: impl Copy + Tr1<As1: Copy> = {
-    let x: impl Copy + Tr1<As1: Copy> = S1;
-    x
-};
-static sdef_et1: impl Copy + Tr1<As1: Copy> = cdef_et1;
-pub fn use_et1() { assert_copy(cdef_et1.mk()); assert_copy(sdef_et1.mk()); }
-
-const cdef_et2: impl Tr1<As1: 'static> = {
-    let x: impl Tr1<As1: 'static> = S1;
-    x
-};
-static sdef_et2: impl Tr1<As1: 'static> = cdef_et2;
-pub fn use_et2() { assert_static(cdef_et2.mk()); assert_static(sdef_et2.mk()); }
-
-const cdef_et3: impl Tr1<As1: Clone + Iterator<Item: Add<u8, Output: Into<u8>>>> = {
-    struct A;
-    impl Tr1 for A {
-        type As1 = core::ops::Range<u8>;
-        fn mk(&self) -> Self::As1 { 0..10 }
-    }
-    let x: impl Tr1<As1: Clone + Iterator<Item: Add<u8, Output: Into<u8>>>> = A;
-    x
-};
-pub fn use_et3() {
-    let _0 = cdef_et3.mk().clone();
-    let mut s = 0u8;
-    for _1 in _0 {
-        let _2 = _1 + 1u8;
-        s += _2.into();
-    }
-    assert_eq!(s, (0..10).map(|x| x + 1).sum());
-}
-
-const cdef_et4: impl Copy + Tr1<As1: for<'a> Tr2<'a>> = {
-    #[derive(Copy, Clone)]
-    struct A;
-    impl Tr1 for A {
-        type As1 = A;
-        fn mk(&self) -> A { A }
-    }
-    impl<'a> Tr2<'a> for A {
-        fn tr2(self) -> &'a Self { &A }
-    }
-    let x: impl Copy + Tr1<As1: for<'a> Tr2<'a>> = A;
-    x
-};
-
-static sdef_et4: impl Copy + Tr1<As1: for<'a> Tr2<'a>> = cdef_et4;
-pub fn use_et4() { assert_forall_tr2(cdef_et4.mk()); assert_forall_tr2(sdef_et4.mk()); }
-
-fn main() {
-    let _ = use_et1();
-    let _ = use_et2();
-    let _ = use_et3();
-    let _ = use_et4();
-}
diff --git a/src/test/ui/associated-type-bounds/lcsit.stderr b/src/test/ui/associated-type-bounds/lcsit.stderr
deleted file mode 100644 (file)
index 11ff03d..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-warning: the feature `impl_trait_in_bindings` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/lcsit.rs:4:12
-   |
-LL | #![feature(impl_trait_in_bindings)]
-   |            ^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(incomplete_features)]` on by default
-   = note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
-
-warning: 1 warning emitted
-
index ab8909d1092baf3411cead06af2b90de50634cd3..41e2d8ec314b777c707f2a661d388ca66aa98383 100644 (file)
@@ -1,12 +1,14 @@
 error[E0277]: the trait bound `<G as GetToInt>::R: ToInt` is not satisfied
   --> $DIR/associated-types-bound-failure.rs:19:19
    |
-LL |     fn to_int(&self) -> isize;
-   |     -------------------------- required by `ToInt::to_int`
-...
 LL |     ToInt::to_int(&g.get())
    |                   ^^^^^^^^ the trait `ToInt` is not implemented for `<G as GetToInt>::R`
    |
+note: required by `ToInt::to_int`
+  --> $DIR/associated-types-bound-failure.rs:6:5
+   |
+LL |     fn to_int(&self) -> isize;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
 help: consider further restricting the associated type
    |
 LL |     where G : GetToInt, <G as GetToInt>::R: ToInt
index e8c11a32bf7fdabb47d0fea9e4dd73725e86af4a..25e80159b0b180cf5e7080206c5a23bb56595df9 100644 (file)
@@ -1,8 +1,11 @@
 error[E0277]: the trait bound `Self: Get` is not satisfied
-  --> $DIR/associated-types-for-unimpl-trait.rs:10:8
+  --> $DIR/associated-types-for-unimpl-trait.rs:10:40
    |
+LL | trait Get {
+   | --------- required by this bound in `Get`
+...
 LL |     fn uhoh<U:Get>(&self, foo: U, bar: <Self as Get>::Value) {}
-   |        ^^^^ the trait `Get` is not implemented for `Self`
+   |                                        ^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `Self`
    |
 help: consider further restricting `Self`
    |
index e3be434698ab9897ad8d5be41eda0450692cd8e7..19500f58aa6883d721d6dbd02e94220635693b2f 100644 (file)
@@ -1,8 +1,11 @@
 error[E0277]: the trait bound `T: Get` is not satisfied
-  --> $DIR/associated-types-no-suitable-bound.rs:11:8
+  --> $DIR/associated-types-no-suitable-bound.rs:11:21
    |
+LL | trait Get {
+   | --------- required by this bound in `Get`
+...
 LL |     fn uhoh<T>(foo: <T as Get>::Value) {}
-   |        ^^^^ the trait `Get` is not implemented for `T`
+   |                     ^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `T`
    |
 help: consider restricting type parameter `T`
    |
index 9dc3414e9edf0de03844b6a79aa388014848f977..0e978f20a6634237dc8ca2a383025ba0b44d3158 100644 (file)
@@ -1,8 +1,11 @@
 error[E0277]: the trait bound `Self: Get` is not satisfied
-  --> $DIR/associated-types-no-suitable-supertrait-2.rs:17:8
+  --> $DIR/associated-types-no-suitable-supertrait-2.rs:17:40
    |
+LL | trait Get {
+   | --------- required by this bound in `Get`
+...
 LL |     fn uhoh<U:Get>(&self, foo: U, bar: <Self as Get>::Value) {}
-   |        ^^^^ the trait `Get` is not implemented for `Self`
+   |                                        ^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `Self`
    |
 help: consider further restricting `Self`
    |
index c2aed3f9de548f953162878e5ed4880a21e2e135..1ec3c05983aefdc193557b482cd82ba8f4945ebc 100644 (file)
@@ -1,8 +1,11 @@
 error[E0277]: the trait bound `Self: Get` is not satisfied
-  --> $DIR/associated-types-no-suitable-supertrait.rs:17:8
+  --> $DIR/associated-types-no-suitable-supertrait.rs:17:40
    |
+LL | trait Get {
+   | --------- required by this bound in `Get`
+...
 LL |     fn uhoh<U:Get>(&self, foo: U, bar: <Self as Get>::Value) {}
-   |        ^^^^ the trait `Get` is not implemented for `Self`
+   |                                        ^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `Self`
    |
 help: consider further restricting `Self`
    |
@@ -10,10 +13,13 @@ LL |     fn uhoh<U:Get>(&self, foo: U, bar: <Self as Get>::Value) where Self: Ge
    |                                                              ^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `(T, U): Get` is not satisfied
-  --> $DIR/associated-types-no-suitable-supertrait.rs:22:8
+  --> $DIR/associated-types-no-suitable-supertrait.rs:22:40
    |
+LL | trait Get {
+   | --------- required by this bound in `Get`
+...
 LL |     fn uhoh<U:Get>(&self, foo: U, bar: <(T, U) as Get>::Value) {}
-   |        ^^^^ the trait `Get` is not implemented for `(T, U)`
+   |                                        ^^^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `(T, U)`
 
 error: aborting due to 2 previous errors
 
index fb842d968676d40d44105519ac78342f41076a36..b6ee1ed733c3e99cc0f82f280bc964083bd170bc 100644 (file)
@@ -1,8 +1,11 @@
 error[E0277]: the trait bound `Self: Get` is not satisfied
-  --> $DIR/associated-types-projection-to-unrelated-trait-in-method-without-default.rs:10:8
+  --> $DIR/associated-types-projection-to-unrelated-trait-in-method-without-default.rs:10:40
    |
+LL | trait Get {
+   | --------- required by this bound in `Get`
+...
 LL |     fn okay<U:Get>(&self, foo: U, bar: <Self as Get>::Value);
-   |        ^^^^ the trait `Get` is not implemented for `Self`
+   |                                        ^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `Self`
    |
 help: consider further restricting `Self`
    |
index 9d084203e3a8664c3962dedb90c85445bc1d1555..5f4b65bd131ee4129757a80d6a85ff776f03d80d 100644 (file)
@@ -1,13 +1,15 @@
 error[E0283]: type annotations needed
   --> $DIR/associated-types-unconstrained.rs:14:20
    |
-LL |     fn bar() -> isize;
-   |     ------------------ required by `Foo::bar`
-...
 LL |     let x: isize = Foo::bar();
    |                    ^^^^^^^^ cannot infer type
    |
    = note: cannot satisfy `_: Foo`
+note: required by `Foo::bar`
+  --> $DIR/associated-types-unconstrained.rs:5:5
+   |
+LL |     fn bar() -> isize;
+   |     ^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
index 1270cd6706aef85ffd6c3c696c76e2c58802ba01..bad736b64c038122dc7988cae58fb89600e997c7 100644 (file)
@@ -11,7 +11,7 @@ fn bug(item: &Self::Item) -> () {
 }
 
 impl<T: Copy + std::ops::Deref> UnsafeCopy<'_, T> for T {
-    //~^ ERROR the trait bound `<T as UnsafeCopy<'b, T>>::Item: Deref` is not satisfied
+    //~^ ERROR the trait bound `for<'b> <T as UnsafeCopy<'b, T>>::Item: Deref` is not satisfied
     type Item = T;
     //~^ ERROR the trait bound `for<'b> <T as UnsafeCopy<'b, T>>::Item: Deref
 }
index cf4ec0babfc219a04b89a9b2bdc0af659c068e4b..49fad4e1b1cb80e975cd9bad2e36fd1c8d9a9eb7 100644 (file)
@@ -14,16 +14,16 @@ LL |     type Item = T;
              <&T as Deref>
              <&mut T as Deref>
 
-error[E0277]: the trait bound `<T as UnsafeCopy<'b, T>>::Item: Deref` is not satisfied
+error[E0277]: the trait bound `for<'b> <T as UnsafeCopy<'b, T>>::Item: Deref` is not satisfied
   --> $DIR/hr-associated-type-projection-1.rs:13:33
    |
 LL | impl<T: Copy + std::ops::Deref> UnsafeCopy<'_, T> for T {
-   |                                 ^^^^^^^^^^^^^^^^^ the trait `Deref` is not implemented for `<T as UnsafeCopy<'b, T>>::Item`
+   |                                 ^^^^^^^^^^^^^^^^^ the trait `for<'b> Deref` is not implemented for `<T as UnsafeCopy<'b, T>>::Item`
    |
 help: consider further restricting the associated type
    |
-LL | impl<T: Copy + std::ops::Deref> UnsafeCopy<'_, T> for T where <T as UnsafeCopy<'b, T>>::Item: Deref {
-   |                                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | impl<T: Copy + std::ops::Deref> UnsafeCopy<'_, T> for T where for<'b> <T as UnsafeCopy<'b, T>>::Item: Deref {
+   |                                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 2 previous errors
 
index b7db5d385829cd2d1f7b5c334919da4f0f56128a..7bf36d5e91515dbff90e8c892258273262f9ccc7 100644 (file)
@@ -1,9 +1,6 @@
 error[E0271]: type mismatch resolving `<() as Array>::Element == &()`
   --> $DIR/issue-44153.rs:18:5
    |
-LL |     fn visit() {}
-   |     ---------- required by `Visit::visit`
-...
 LL |     <() as Visit>::visit();
    |     ^^^^^^^^^^^^^^^^^^^^ expected `&()`, found `()`
    |
@@ -12,6 +9,11 @@ note: required because of the requirements on the impl of `Visit` for `()`
    |
 LL | impl<'a> Visit for () where
    |          ^^^^^     ^^
+note: required by `Visit::visit`
+  --> $DIR/issue-44153.rs:6:5
+   |
+LL |     fn visit() {}
+   |     ^^^^^^^^^^
 
 error: aborting due to previous error
 
index 9694742200ef07d658e0a5606156f0f04f53a4ba..36fb73a8dde247e5b8b03bc273512fab66b36605 100644 (file)
@@ -3,6 +3,8 @@ error[E0726]: implicit elided lifetime not allowed here
    |
 LL | async fn error(lt: HasLifetime) {
    |                    ^^^^^^^^^^^- help: indicate the anonymous lifetime: `<'_>`
+   |
+   = note: assuming a `'static` lifetime...
 
 error: aborting due to previous error
 
index ad661fb2833fa08e7992ea0d4de9a6eff2372da0..ba97e135790c16a0ded828d8426afe0448f178c2 100644 (file)
@@ -5,7 +5,11 @@ LL |     foo()?;
    |     ^^^^^^ the `?` operator cannot be applied to type `impl Future`
    |
    = help: the trait `Try` is not implemented for `impl Future`
-   = note: required by `branch`
+note: required by `branch`
+  --> $SRC_DIR/core/src/ops/try_trait.rs:LL:COL
+   |
+LL |     fn branch(self) -> ControlFlow<Self::Residual, Self::Output>;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 help: consider `await`ing on the `Future`
    |
 LL |     foo().await?;
@@ -18,7 +22,11 @@ LL |     t?;
    |     ^^ the `?` operator cannot be applied to type `T`
    |
    = help: the trait `Try` is not implemented for `T`
-   = note: required by `branch`
+note: required by `branch`
+  --> $SRC_DIR/core/src/ops/try_trait.rs:LL:COL
+   |
+LL |     fn branch(self) -> ControlFlow<Self::Residual, Self::Output>;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 help: consider `await`ing on the `Future`
    |
 LL |     t.await?;
index fb1f8e4ffd251fed8cae966a820a0177bba95e5a..e20e2e8f6ba3848bc327b112c2f449d88b8548c3 100644 (file)
@@ -25,7 +25,11 @@ LL |     [1; ().await];
    |         ^^^^^^^^ `()` is not a future
    |
    = help: the trait `Future` is not implemented for `()`
-   = note: required by `poll`
+note: required by `poll`
+  --> $SRC_DIR/core/src/future/future.rs:LL:COL
+   |
+LL |     fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output>;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 4 previous errors
 
index 170dcf581ed263ca9303baac07cc097152ddfd66..e28ba74eb6339dd8ed00b71df6c07a21528b0af6 100644 (file)
@@ -5,7 +5,11 @@ LL |     test()?;
    |     ^^^^^^^ the `?` operator cannot be applied to type `impl Future`
    |
    = help: the trait `Try` is not implemented for `impl Future`
-   = note: required by `branch`
+note: required by `branch`
+  --> $SRC_DIR/core/src/ops/try_trait.rs:LL:COL
+   |
+LL |     fn branch(self) -> ControlFlow<Self::Residual, Self::Output>;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the `?` operator can only be used in an async function that returns `Result` or `Option` (or another type that implements `FromResidual`)
   --> $DIR/issue-84841.rs:9:11
@@ -21,7 +25,11 @@ LL | | }
    | |_- this function should return `Result` or `Option` to accept `?`
    |
    = help: the trait `FromResidual<_>` is not implemented for `()`
-   = note: required by `from_residual`
+note: required by `from_residual`
+  --> $SRC_DIR/core/src/ops/try_trait.rs:LL:COL
+   |
+LL |     fn from_residual(residual: R) -> Self;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 2 previous errors
 
index c879a65bc7f77008f553ebdfb5155454e8e9b992..946b8d19e6936a11e162723db023fbe1694f0c04 100644 (file)
@@ -34,7 +34,11 @@ LL |     (|_| 2333).await;
    |     ^^^^^^^^^^^^^^^^ `[closure@$DIR/issue-62009-1.rs:12:5: 12:15]` is not a future
    |
    = help: the trait `Future` is not implemented for `[closure@$DIR/issue-62009-1.rs:12:5: 12:15]`
-   = note: required by `poll`
+note: required by `poll`
+  --> $SRC_DIR/core/src/future/future.rs:LL:COL
+   |
+LL |     fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output>;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 4 previous errors
 
index c4d21de8aaf75b4bfc6f894f9d3a9133e5326e1a..8c581ff2229fc00889d0b9684cd75de5b2750938 100644 (file)
@@ -10,7 +10,11 @@ note: required because it appears within the type `Sleep`
    |
 LL | struct Sleep(std::marker::PhantomPinned);
    |        ^^^^^
-   = note: required by `Pin::<P>::new`
+note: required by `Pin::<P>::new`
+  --> $SRC_DIR/core/src/pin.rs:LL:COL
+   |
+LL |     pub const fn new(pointer: P) -> Pin<P> {
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
index a3f122a466361fc4e3dd033c6f002a739ce0d92d..e8bb4aca9a9c9d5b92174d6cd4eb8cdb1228eb54 100644 (file)
@@ -11,7 +11,11 @@ LL | |     }
    | |_____- this function should return `Result` or `Option` to accept `?`
    |
    = help: the trait `FromResidual<Option<Infallible>>` is not implemented for `{integer}`
-   = note: required by `from_residual`
+note: required by `from_residual`
+  --> $SRC_DIR/core/src/ops/try_trait.rs:LL:COL
+   |
+LL |     fn from_residual(residual: R) -> Self;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the `?` operator can only be used in an async closure that returns `Result` or `Option` (or another type that implements `FromResidual`)
   --> $DIR/try-on-option-in-async.rs:17:10
@@ -26,7 +30,11 @@ LL | |     };
    | |_____- this function should return `Result` or `Option` to accept `?`
    |
    = help: the trait `FromResidual<Option<Infallible>>` is not implemented for `u32`
-   = note: required by `from_residual`
+note: required by `from_residual`
+  --> $SRC_DIR/core/src/ops/try_trait.rs:LL:COL
+   |
+LL |     fn from_residual(residual: R) -> Self;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the `?` operator can only be used in an async function that returns `Result` or `Option` (or another type that implements `FromResidual`)
   --> $DIR/try-on-option-in-async.rs:26:6
@@ -41,7 +49,11 @@ LL | | }
    | |_- this function should return `Result` or `Option` to accept `?`
    |
    = help: the trait `FromResidual<Option<Infallible>>` is not implemented for `u32`
-   = note: required by `from_residual`
+note: required by `from_residual`
+  --> $SRC_DIR/core/src/ops/try_trait.rs:LL:COL
+   |
+LL |     fn from_residual(residual: R) -> Self;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 3 previous errors
 
index 7a5ba16461f76001b598fd91fd0a6023a388add2..5e3b43a47eeeef69952049d75d122a9489cb600c 100644 (file)
@@ -5,7 +5,11 @@ LL |     let _ = Box::into_boxed_slice(boxed_slice);
    |                                   ^^^^^^^^^^^ doesn't have a size known at compile-time
    |
    = help: the trait `Sized` is not implemented for `[u8]`
-   = note: required by `Box::<T, A>::into_boxed_slice`
+note: required by `Box::<T, A>::into_boxed_slice`
+  --> $SRC_DIR/alloc/src/boxed.rs:LL:COL
+   |
+LL |     pub fn into_boxed_slice(boxed: Self) -> Box<[T], A> {
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
   --> $DIR/into-boxed-slice-fail.rs:7:13
@@ -23,7 +27,11 @@ LL |     let _ = Box::into_boxed_slice(boxed_trait);
    |                                   ^^^^^^^^^^^ doesn't have a size known at compile-time
    |
    = help: the trait `Sized` is not implemented for `dyn Debug`
-   = note: required by `Box::<T, A>::into_boxed_slice`
+note: required by `Box::<T, A>::into_boxed_slice`
+  --> $SRC_DIR/alloc/src/boxed.rs:LL:COL
+   |
+LL |     pub fn into_boxed_slice(boxed: Self) -> Box<[T], A> {
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the size for values of type `dyn Debug` cannot be known at compilation time
   --> $DIR/into-boxed-slice-fail.rs:11:13
index 3cd60369454930eb138acded147f096dcdd24919..ebd885a7d323f641baea3fd84a6abcd9602a1798 100644 (file)
@@ -1,15 +1,17 @@
 error[E0277]: the trait bound `{float}: Foo` is not satisfied
   --> $DIR/type_wf.rs:18:13
    |
-LL | struct S<T: Foo> {
-   | ---------------- required by `S`
-...
 LL |     let s = S {
    |             ^ the trait `Foo` is not implemented for `{float}`
    |
    = help: the following implementations were found:
              <Option<T> as Foo>
              <i32 as Foo>
+note: required by `S`
+  --> $DIR/type_wf.rs:6:1
+   |
+LL | struct S<T: Foo> {
+   | ^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
index 72ef5b3b962c734d5386c07b0796aca96c57007b..ffe0bce6f0fd8b01d0c079e221c4ba9e3092a07e 100644 (file)
@@ -5,7 +5,7 @@ LL |     (&|_| ()) as &dyn for<'x> Fn(<u32 as T<'x>>::V);
    |     ^^------^
    |     | |
    |     | found signature of `fn(u16) -> _`
-   |     expected signature of `fn(<u32 as T<'x>>::V) -> _`
+   |     expected signature of `for<'x> fn(<u32 as T<'x>>::V) -> _`
    |
    = note: required for the cast to the object type `dyn for<'x> Fn(<u32 as T<'x>>::V)`
 
index 7dabd97b94e823d93462b0cc5c8b61ff4789cddf..cfcef9699f3721f7c91af8e607cb7eaa414168bc 100644 (file)
@@ -1,10 +1,10 @@
-error[E0119]: conflicting implementations of trait `Trait` for type `for<'r> fn(fn(&'r ()))`
+error[E0119]: conflicting implementations of trait `Trait` for type `for<'r> fn(for<'r> fn(&'r ()))`
   --> $DIR/coherence-fn-covariant-bound-vs-static.rs:17:1
    |
 LL | impl Trait for for<'r> fn(fn(&'r ())) {}
    | ------------------------------------- first implementation here
 LL | impl<'a> Trait for fn(fn(&'a ())) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `for<'r> fn(fn(&'r ()))`
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `for<'r> fn(for<'r> fn(&'r ()))`
    |
    = note: this behavior recently changed as a result of a bug fix; see rust-lang/rust#56105 for details
 
index e0e6029252c00b3471084c478d037e1e4e86f45e..319e6c2c032a0e067bf9fd2009cfe3416fbc63f9 100644 (file)
@@ -1,8 +1,8 @@
 error[E0038]: the trait `Foo` cannot be made into an object
-  --> $DIR/object-safety-err-ret.rs:17:15
+  --> $DIR/object-safety-err-ret.rs:17:16
    |
 LL | fn use_dyn(v: &dyn Foo) {
-   |               ^^^^^^^^ `Foo` cannot be made into an object
+   |                ^^^^^^^ `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>
index d894fa90ba9e1c72a67bf84ea293541be55f9895..09986f623fc4b393b742aa9d60243a50d2d1fef8 100644 (file)
@@ -3,9 +3,12 @@ error[E0277]: the trait bound `[Adt; _]: Foo` is not satisfied
    |
 LL |         <[Adt; std::mem::size_of::<Self::Assoc>()] as Foo>::bar()
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `[Adt; _]`
-...
+   |
+note: required by `Foo::bar`
+  --> $DIR/dont-evaluate-array-len-on-err-1.rs:19:5
+   |
 LL |     fn bar() {}
-   |     -------- required by `Foo::bar`
+   |     ^^^^^^^^
 
 error: aborting due to previous error
 
index e0e1423ba0107083d9b9583e57cb6eef12a0810e..4e89e4a3b17e97b285dc5466b8145d2b1cc45f48 100644 (file)
@@ -1,9 +1,6 @@
 error[E0277]: the trait bound `(): Foo<N>` is not satisfied
   --> $DIR/exhaustive-value.rs:266:5
    |
-LL |     fn test() {}
-   |     --------- required by `Foo::test`
-...
 LL |     <() as Foo<N>>::test()
    |     ^^^^^^^^^^^^^^^^^^^^ the trait `Foo<N>` is not implemented for `()`
    |
@@ -13,6 +10,11 @@ LL |     <() as Foo<N>>::test()
              <() as Foo<101_u8>>
              <() as Foo<102_u8>>
            and 252 others
+note: required by `Foo::test`
+  --> $DIR/exhaustive-value.rs:6:5
+   |
+LL |     fn test() {}
+   |     ^^^^^^^^^
 
 error: aborting due to previous error
 
index e0e1423ba0107083d9b9583e57cb6eef12a0810e..4e89e4a3b17e97b285dc5466b8145d2b1cc45f48 100644 (file)
@@ -1,9 +1,6 @@
 error[E0277]: the trait bound `(): Foo<N>` is not satisfied
   --> $DIR/exhaustive-value.rs:266:5
    |
-LL |     fn test() {}
-   |     --------- required by `Foo::test`
-...
 LL |     <() as Foo<N>>::test()
    |     ^^^^^^^^^^^^^^^^^^^^ the trait `Foo<N>` is not implemented for `()`
    |
@@ -13,6 +10,11 @@ LL |     <() as Foo<N>>::test()
              <() as Foo<101_u8>>
              <() as Foo<102_u8>>
            and 252 others
+note: required by `Foo::test`
+  --> $DIR/exhaustive-value.rs:6:5
+   |
+LL |     fn test() {}
+   |     ^^^^^^^^^
 
 error: aborting due to previous error
 
index 6830288acc0ad25c49e82e5b1b7fcf36c5a085b1..382dd0ee5a64eaa909cbc9b8fdb4d26a2427ed08 100644 (file)
@@ -1,16 +1,18 @@
 error[E0277]: the trait bound `A<{_: usize}>: Bar<{_: usize}>` is not satisfied
   --> $DIR/unused-substs-1.rs:12:13
    |
-LL | / struct A<const N: usize>
-LL | | where
-LL | |     A<N>: Bar<N>;
-   | |_________________- required by `A`
-...
-LL |       let _ = A;
-   |               ^ the trait `Bar<{_: usize}>` is not implemented for `A<{_: usize}>`
+LL |     let _ = A;
+   |             ^ the trait `Bar<{_: usize}>` is not implemented for `A<{_: usize}>`
    |
    = help: the following implementations were found:
              <A<7_usize> as Bar<N>>
+note: required by `A`
+  --> $DIR/unused-substs-1.rs:7:1
+   |
+LL | / struct A<const N: usize>
+LL | | where
+LL | |     A<N>: Bar<N>;
+   | |_________________^
 
 error: aborting due to previous error
 
index a22296a7b0085c0d89a4ef5863be03db353d3cb8..42a285a6eab4972fcfc2c9e235949f9d77a4d238 100644 (file)
@@ -13,6 +13,7 @@
 pub const UNDERFLOW: *const u16 = unsafe { [0u16; 1].as_ptr().offset(isize::MIN) }; //~NOTE
 pub const OVERFLOW_ADDRESS_SPACE: *const u8 = unsafe { (usize::MAX as *const u8).offset(2) }; //~NOTE
 pub const UNDERFLOW_ADDRESS_SPACE: *const u8 = unsafe { (1 as *const u8).offset(-2) }; //~NOTE
+pub const NEGATIVE_OFFSET: *const u8 = unsafe { [0u8; 1].as_ptr().wrapping_offset(-2).offset(-2) }; //~NOTE
 
 pub const ZERO_SIZED_ALLOC: *const u8 = unsafe { [0u8; 0].as_ptr().offset(1) }; //~NOTE
 pub const DANGLING: *const u8 = unsafe { ptr::NonNull::<u8>::dangling().as_ptr().offset(4) }; //~NOTE
index 4f7c4f92060a24352fbd799251f2487fd7880413..66a2722ed4acd1d244f4c9818fe1589ddb35875f 100644 (file)
@@ -102,13 +102,27 @@ error[E0080]: evaluation of constant value failed
 LL |         unsafe { intrinsics::offset(self, count) }
    |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |                  |
-   |                  pointer arithmetic failed: allocN has size 0, so pointer to 1 bytes starting at offset 0 is out-of-bounds
+   |                  pointer arithmetic failed: allocN has size 1, so pointer to 2 bytes starting at offset -4 is out-of-bounds
    |                  inside `ptr::const_ptr::<impl *const u8>::offset` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
    | 
-  ::: $DIR/offset_ub.rs:17:50
+  ::: $DIR/offset_ub.rs:16:49
+   |
+LL | pub const NEGATIVE_OFFSET: *const u8 = unsafe { [0u8; 1].as_ptr().wrapping_offset(-2).offset(-2) };
+   |                                                 ------------------------------------------------ inside `NEGATIVE_OFFSET` at $DIR/offset_ub.rs:16:49
+
+error[E0080]: evaluation of constant value failed
+  --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
+   |
+LL |         unsafe { intrinsics::offset(self, count) }
+   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                  |
+   |                  pointer arithmetic failed: allocN has size 0, so pointer to 1 byte starting at offset 0 is out-of-bounds
+   |                  inside `ptr::const_ptr::<impl *const u8>::offset` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
+   | 
+  ::: $DIR/offset_ub.rs:18:50
    |
 LL | pub const ZERO_SIZED_ALLOC: *const u8 = unsafe { [0u8; 0].as_ptr().offset(1) };
-   |                                                  --------------------------- inside `ZERO_SIZED_ALLOC` at $DIR/offset_ub.rs:17:50
+   |                                                  --------------------------- inside `ZERO_SIZED_ALLOC` at $DIR/offset_ub.rs:18:50
 
 error[E0080]: evaluation of constant value failed
   --> $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL
@@ -119,10 +133,10 @@ LL |         unsafe { intrinsics::offset(self, count) as *mut T }
    |                  0x1 is not a valid pointer
    |                  inside `ptr::mut_ptr::<impl *mut u8>::offset` at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL
    | 
-  ::: $DIR/offset_ub.rs:18:42
+  ::: $DIR/offset_ub.rs:19:42
    |
 LL | pub const DANGLING: *const u8 = unsafe { ptr::NonNull::<u8>::dangling().as_ptr().offset(4) };
-   |                                          ------------------------------------------------- inside `DANGLING` at $DIR/offset_ub.rs:18:42
+   |                                          ------------------------------------------------- inside `DANGLING` at $DIR/offset_ub.rs:19:42
 
 error[E0080]: evaluation of constant value failed
   --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
@@ -133,10 +147,10 @@ LL |         unsafe { intrinsics::offset(self, count) }
    |                  pointer arithmetic failed: 0x0 is not a valid pointer
    |                  inside `ptr::const_ptr::<impl *const u8>::offset` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
    | 
-  ::: $DIR/offset_ub.rs:21:50
+  ::: $DIR/offset_ub.rs:22:50
    |
 LL | pub const NULL_OFFSET_ZERO: *const u8 = unsafe { ptr::null::<u8>().offset(0) };
-   |                                                  --------------------------- inside `NULL_OFFSET_ZERO` at $DIR/offset_ub.rs:21:50
+   |                                                  --------------------------- inside `NULL_OFFSET_ZERO` at $DIR/offset_ub.rs:22:50
 
 error[E0080]: evaluation of constant value failed
   --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
@@ -147,11 +161,11 @@ LL |         unsafe { intrinsics::offset(self, count) }
    |                  0x7f..f is not a valid pointer
    |                  inside `ptr::const_ptr::<impl *const u8>::offset` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
    | 
-  ::: $DIR/offset_ub.rs:24:47
+  ::: $DIR/offset_ub.rs:25:47
    |
 LL | pub const UNDERFLOW_ABS: *const u8 = unsafe { (usize::MAX as *const u8).offset(isize::MIN) };
-   |                                               -------------------------------------------- inside `UNDERFLOW_ABS` at $DIR/offset_ub.rs:24:47
+   |                                               -------------------------------------------- inside `UNDERFLOW_ABS` at $DIR/offset_ub.rs:25:47
 
-error: aborting due to 11 previous errors
+error: aborting due to 12 previous errors
 
 For more information about this error, try `rustc --explain E0080`.
index 8967a7c6d33c7cd55cf8eb66ed34e82fa9be34b6..e848ddc55b7dff8be1152ab5cbfdef8a7dc9bebd 100644 (file)
@@ -1,6 +1,8 @@
 error[E0277]: the trait bound `TestDescAndFn: Testable` is not satisfied
   --> $DIR/mismatch.rs:9:1
    |
+LL | #[test]
+   | ------- in this procedural macro expansion
 LL | fn wrong_kind(){}
    | ^^^^^^^^^^^^^^^^^ the trait `Testable` is not implemented for `TestDescAndFn`
    |
index b847000a81d80089c9d3bc98a1c043b4494d0962..7e579ec22dd42762b36768d7a2aa463a3d9c25e9 100644 (file)
@@ -1,6 +1,6 @@
 trait Foo {
     #[derive(Clone)]
-    //~^ ERROR `derive` may only be applied to structs, enums and unions
+    //~^ ERROR `derive` may only be applied to `struct`s, `enum`s and `union`s
     type Bar;
 }
 
@@ -8,7 +8,7 @@ trait Foo {
 
 impl Bar {
     #[derive(Clone)]
-    //~^ ERROR `derive` may only be applied to structs, enums and unions
+    //~^ ERROR `derive` may only be applied to `struct`s, `enum`s and `union`s
     fn bar(&self) {}
 }
 
index e892d3f0863036ff6c40b2da5e30d8fbd92204cd..1fd97bdd5ec62f4f24df1a1d0bec0ee4fbe75891 100644 (file)
@@ -1,14 +1,20 @@
-error[E0774]: `derive` may only be applied to structs, enums and unions
+error[E0774]: `derive` may only be applied to `struct`s, `enum`s and `union`s
   --> $DIR/derive-on-trait-item-or-impl-item.rs:2:5
    |
 LL |     #[derive(Clone)]
-   |     ^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^ not applicable here
+LL |
+LL |     type Bar;
+   |     --------- not a `struct`, `enum` or `union`
 
-error[E0774]: `derive` may only be applied to structs, enums and unions
+error[E0774]: `derive` may only be applied to `struct`s, `enum`s and `union`s
   --> $DIR/derive-on-trait-item-or-impl-item.rs:10:5
    |
 LL |     #[derive(Clone)]
-   |     ^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^ not applicable here
+LL |
+LL |     fn bar(&self) {}
+   |     ---------------- not a `struct`, `enum` or `union`
 
 error: aborting due to 2 previous errors
 
index 3d62bd8e8e7918d9fc52cc1a89c68fb8d410a679..c5bc50e407b25787dbd8d5ca2278e6597311a926 100644 (file)
@@ -1,10 +1,17 @@
 error[E0277]: the trait bound `Error: Clone` is not satisfied
   --> $DIR/derives-span-Clone-enum-struct-variant.rs:9:6
    |
+LL | #[derive(Clone)]
+   |          ----- in this derive macro expansion
+...
 LL |      x: Error
    |      ^^^^^^^^ the trait `Clone` is not implemented for `Error`
    |
-   = note: required by `clone`
+note: required by `clone`
+  --> $SRC_DIR/core/src/clone.rs:LL:COL
+   |
+LL |     fn clone(&self) -> Self;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^
    = note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: aborting due to previous error
index c855ec8e99327abb0d1311cb6311e5357a0924ac..a6dc818eb6fe4ea4786377c627695c123ef41ae3 100644 (file)
@@ -1,10 +1,17 @@
 error[E0277]: the trait bound `Error: Clone` is not satisfied
   --> $DIR/derives-span-Clone-enum.rs:9:6
    |
+LL | #[derive(Clone)]
+   |          ----- in this derive macro expansion
+...
 LL |      Error
    |      ^^^^^ the trait `Clone` is not implemented for `Error`
    |
-   = note: required by `clone`
+note: required by `clone`
+  --> $SRC_DIR/core/src/clone.rs:LL:COL
+   |
+LL |     fn clone(&self) -> Self;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^
    = note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: aborting due to previous error
index 522ec9719ed41ca9277205fa21c34345aa5f58ce..cf7b9ec276e2542e52adadf8f645899bad42f4d5 100644 (file)
@@ -1,10 +1,17 @@
 error[E0277]: the trait bound `Error: Clone` is not satisfied
   --> $DIR/derives-span-Clone-struct.rs:8:5
    |
+LL | #[derive(Clone)]
+   |          ----- in this derive macro expansion
+LL | struct Struct {
 LL |     x: Error
    |     ^^^^^^^^ the trait `Clone` is not implemented for `Error`
    |
-   = note: required by `clone`
+note: required by `clone`
+  --> $SRC_DIR/core/src/clone.rs:LL:COL
+   |
+LL |     fn clone(&self) -> Self;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^
    = note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: aborting due to previous error
index b1f3e72f0d5634111daecb82bf8516adb1ab90c5..80733d62730d7a2fc78e3ddc5c377d34ec996cce 100644 (file)
@@ -1,10 +1,17 @@
 error[E0277]: the trait bound `Error: Clone` is not satisfied
   --> $DIR/derives-span-Clone-tuple-struct.rs:8:5
    |
+LL | #[derive(Clone)]
+   |          ----- in this derive macro expansion
+LL | struct Struct(
 LL |     Error
    |     ^^^^^ the trait `Clone` is not implemented for `Error`
    |
-   = note: required by `clone`
+note: required by `clone`
+  --> $SRC_DIR/core/src/clone.rs:LL:COL
+   |
+LL |     fn clone(&self) -> Self;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^
    = note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: aborting due to previous error
index 4ec89fe729f80720d173ada907db8a72a25cde29..bdcbbf0c75787cf67e4034ba329c2e15e8ae60ca 100644 (file)
@@ -1,6 +1,9 @@
 error[E0277]: `Error` doesn't implement `Debug`
   --> $DIR/derives-span-Debug-enum-struct-variant.rs:9:6
    |
+LL | #[derive(Debug)]
+   |          ----- in this derive macro expansion
+...
 LL |      x: Error
    |      ^^^^^^^^ `Error` cannot be formatted using `{:?}`
    |
index d564b6ad76b713660f54109008159b9aa2b22182..4ffb75935af9b996146a5a3e92a6719a31818a3e 100644 (file)
@@ -1,6 +1,9 @@
 error[E0277]: `Error` doesn't implement `Debug`
   --> $DIR/derives-span-Debug-enum.rs:9:6
    |
+LL | #[derive(Debug)]
+   |          ----- in this derive macro expansion
+...
 LL |      Error
    |      ^^^^^ `Error` cannot be formatted using `{:?}`
    |
index 352141c7e336b2327f4c6bc3e410b52cc8841635..74d2460bb6906ba38e69f66b3f0c2e120d7d0a28 100644 (file)
@@ -1,6 +1,9 @@
 error[E0277]: `Error` doesn't implement `Debug`
   --> $DIR/derives-span-Debug-struct.rs:8:5
    |
+LL | #[derive(Debug)]
+   |          ----- in this derive macro expansion
+LL | struct Struct {
 LL |     x: Error
    |     ^^^^^^^^ `Error` cannot be formatted using `{:?}`
    |
index 65765490183b8a994bb33e3f4bbeb638cea32f90..34ddb4e594377927288768dc0946b4f08ff8aa0f 100644 (file)
@@ -1,6 +1,9 @@
 error[E0277]: `Error` doesn't implement `Debug`
   --> $DIR/derives-span-Debug-tuple-struct.rs:8:5
    |
+LL | #[derive(Debug)]
+   |          ----- in this derive macro expansion
+LL | struct Struct(
 LL |     Error
    |     ^^^^^ `Error` cannot be formatted using `{:?}`
    |
index b4cf1119eeb8ab752801cce4e2309e0c927bf1b8..c60b6ac456ebf962e42821018a919f461e06bbc5 100644 (file)
@@ -1,10 +1,17 @@
 error[E0277]: the trait bound `Error: Default` is not satisfied
   --> $DIR/derives-span-Default-struct.rs:8:5
    |
+LL | #[derive(Default)]
+   |          ------- in this derive macro expansion
+LL | struct Struct {
 LL |     x: Error
    |     ^^^^^^^^ the trait `Default` is not implemented for `Error`
    |
-   = note: required by `std::default::Default::default`
+note: required by `std::default::Default::default`
+  --> $SRC_DIR/core/src/default.rs:LL:COL
+   |
+LL |     fn default() -> Self;
+   |     ^^^^^^^^^^^^^^^^^^^^^
    = note: this error originates in the derive macro `Default` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: aborting due to previous error
index 62661a659be58c1fbdcf4654bb33870e710f3635..ed342f539da03e3f80e567b0bd8e90ed3cde3a39 100644 (file)
@@ -1,10 +1,17 @@
 error[E0277]: the trait bound `Error: Default` is not satisfied
   --> $DIR/derives-span-Default-tuple-struct.rs:8:5
    |
+LL | #[derive(Default)]
+   |          ------- in this derive macro expansion
+LL | struct Struct(
 LL |     Error
    |     ^^^^^ the trait `Default` is not implemented for `Error`
    |
-   = note: required by `std::default::Default::default`
+note: required by `std::default::Default::default`
+  --> $SRC_DIR/core/src/default.rs:LL:COL
+   |
+LL |     fn default() -> Self;
+   |     ^^^^^^^^^^^^^^^^^^^^^
    = note: this error originates in the derive macro `Default` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: aborting due to previous error
index b14f2f8f0735c713338bb3e74a270e89c53f472d..0a764053824562e9e265d3172dfb7bb7a0531b72 100644 (file)
@@ -1,6 +1,9 @@
 error[E0277]: the trait bound `Error: Eq` is not satisfied
   --> $DIR/derives-span-Eq-enum-struct-variant.rs:9:6
    |
+LL | #[derive(Eq,PartialEq)]
+   |          -- in this derive macro expansion
+...
 LL |      x: Error
    |      ^^^^^^^^ the trait `Eq` is not implemented for `Error`
    | 
index ed7e6936f56c51ddd5ff5777f784c2e52ee7ff77..c17e2c518aa76246498c77ecafed04f9a6140bc8 100644 (file)
@@ -1,6 +1,9 @@
 error[E0277]: the trait bound `Error: Eq` is not satisfied
   --> $DIR/derives-span-Eq-enum.rs:9:6
    |
+LL | #[derive(Eq,PartialEq)]
+   |          -- in this derive macro expansion
+...
 LL |      Error
    |      ^^^^^ the trait `Eq` is not implemented for `Error`
    | 
index ec26c5617210781834e76e3bfd35340f0757cf10..7a7640b40f627980bcaedd7aa7b3b0dca9fa4b15 100644 (file)
@@ -1,6 +1,9 @@
 error[E0277]: the trait bound `Error: Eq` is not satisfied
   --> $DIR/derives-span-Eq-struct.rs:8:5
    |
+LL | #[derive(Eq,PartialEq)]
+   |          -- in this derive macro expansion
+LL | struct Struct {
 LL |     x: Error
    |     ^^^^^^^^ the trait `Eq` is not implemented for `Error`
    | 
index a41acfbf5b515cda3349f66bc7afb894a084c2f1..35932986b0499660fd2f6b6e1b8621a7e3b76be4 100644 (file)
@@ -1,6 +1,9 @@
 error[E0277]: the trait bound `Error: Eq` is not satisfied
   --> $DIR/derives-span-Eq-tuple-struct.rs:8:5
    |
+LL | #[derive(Eq,PartialEq)]
+   |          -- in this derive macro expansion
+LL | struct Struct(
 LL |     Error
    |     ^^^^^ the trait `Eq` is not implemented for `Error`
    | 
index fef7b8f75ac6f0bb69a6c2e595e4ffa455c238ed..4616dadbe6bf7e7998c272f08901bcaf1aaa284b 100644 (file)
@@ -1,6 +1,9 @@
 error[E0277]: the trait bound `Error: Hash` is not satisfied
   --> $DIR/derives-span-Hash-enum-struct-variant.rs:9:6
    |
+LL | #[derive(Hash)]
+   |          ---- in this derive macro expansion
+...
 LL |      x: Error
    |      ^^^^^^^^ the trait `Hash` is not implemented for `Error`
    | 
index 90c5f91af919df7134f22947b08f8f9554974d86..ffc7f7bb7daafd2640ad7b97f02c3e09057efafe 100644 (file)
@@ -1,6 +1,9 @@
 error[E0277]: the trait bound `Error: Hash` is not satisfied
   --> $DIR/derives-span-Hash-enum.rs:8:6
    |
+LL | #[derive(Hash)]
+   |          ---- in this derive macro expansion
+...
 LL |      Error
    |      ^^^^^ the trait `Hash` is not implemented for `Error`
    | 
index b48828f439e1fcd306276021213a2e233ae9b6c1..14aebb4faace9b898f8c929941712391f45e6452 100644 (file)
@@ -1,6 +1,9 @@
 error[E0277]: the trait bound `Error: Hash` is not satisfied
   --> $DIR/derives-span-Hash-struct.rs:8:5
    |
+LL | #[derive(Hash)]
+   |          ---- in this derive macro expansion
+LL | struct Struct {
 LL |     x: Error
    |     ^^^^^^^^ the trait `Hash` is not implemented for `Error`
    | 
index 3db0299192f05a5a988b706fd70ee8d8a92f120f..50139dc3f0a7950824461cdbeb5d6d6d4724b1fd 100644 (file)
@@ -1,6 +1,9 @@
 error[E0277]: the trait bound `Error: Hash` is not satisfied
   --> $DIR/derives-span-Hash-tuple-struct.rs:8:5
    |
+LL | #[derive(Hash)]
+   |          ---- in this derive macro expansion
+LL | struct Struct(
 LL |     Error
    |     ^^^^^ the trait `Hash` is not implemented for `Error`
    | 
index 9f77122286ab66fce00fdb08409330d4dfb1dfe7..1e1cd715e6479343fc3ba6b9828a0a8d9cb8c6bd 100644 (file)
@@ -1,10 +1,17 @@
 error[E0277]: the trait bound `Error: Ord` is not satisfied
   --> $DIR/derives-span-Ord-enum-struct-variant.rs:9:6
    |
+LL | #[derive(Ord,Eq,PartialOrd,PartialEq)]
+   |          --- in this derive macro expansion
+...
 LL |      x: Error
    |      ^^^^^^^^ the trait `Ord` is not implemented for `Error`
    |
-   = note: required by `std::cmp::Ord::cmp`
+note: required by `std::cmp::Ord::cmp`
+  --> $SRC_DIR/core/src/cmp.rs:LL:COL
+   |
+LL |     fn cmp(&self, other: &Self) -> Ordering;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: this error originates in the derive macro `Ord` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: aborting due to previous error
index f5d2dd3daefb2e6b4f1dda5666cef0d9c468bef6..43abe9a954738ca3cbe4f86009de01b75162107d 100644 (file)
@@ -1,10 +1,17 @@
 error[E0277]: the trait bound `Error: Ord` is not satisfied
   --> $DIR/derives-span-Ord-enum.rs:9:6
    |
+LL | #[derive(Ord,Eq,PartialOrd,PartialEq)]
+   |          --- in this derive macro expansion
+...
 LL |      Error
    |      ^^^^^ the trait `Ord` is not implemented for `Error`
    |
-   = note: required by `std::cmp::Ord::cmp`
+note: required by `std::cmp::Ord::cmp`
+  --> $SRC_DIR/core/src/cmp.rs:LL:COL
+   |
+LL |     fn cmp(&self, other: &Self) -> Ordering;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: this error originates in the derive macro `Ord` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: aborting due to previous error
index 7a61ca483127910ee5f1748ce2143d65fd76bdcd..44f6bab08c127854a2dd332374e30d3f6eb7e329 100644 (file)
@@ -1,10 +1,17 @@
 error[E0277]: the trait bound `Error: Ord` is not satisfied
   --> $DIR/derives-span-Ord-struct.rs:8:5
    |
+LL | #[derive(Ord,Eq,PartialOrd,PartialEq)]
+   |          --- in this derive macro expansion
+LL | struct Struct {
 LL |     x: Error
    |     ^^^^^^^^ the trait `Ord` is not implemented for `Error`
    |
-   = note: required by `std::cmp::Ord::cmp`
+note: required by `std::cmp::Ord::cmp`
+  --> $SRC_DIR/core/src/cmp.rs:LL:COL
+   |
+LL |     fn cmp(&self, other: &Self) -> Ordering;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: this error originates in the derive macro `Ord` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: aborting due to previous error
index cd67d9ce98e09fa4b759f52085228a9a7021eee0..e604018245ae3a6aeb0e7882a4f36337ee85245a 100644 (file)
@@ -1,10 +1,17 @@
 error[E0277]: the trait bound `Error: Ord` is not satisfied
   --> $DIR/derives-span-Ord-tuple-struct.rs:8:5
    |
+LL | #[derive(Ord,Eq,PartialOrd,PartialEq)]
+   |          --- in this derive macro expansion
+LL | struct Struct(
 LL |     Error
    |     ^^^^^ the trait `Ord` is not implemented for `Error`
    |
-   = note: required by `std::cmp::Ord::cmp`
+note: required by `std::cmp::Ord::cmp`
+  --> $SRC_DIR/core/src/cmp.rs:LL:COL
+   |
+LL |     fn cmp(&self, other: &Self) -> Ordering;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: this error originates in the derive macro `Ord` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: aborting due to previous error
index a579d695700d4286924395298c91582dbc313e24..abcba6da8aaee74c3e06b4cf401456a211fa9b37 100644 (file)
@@ -1,6 +1,9 @@
 error[E0369]: binary operation `==` cannot be applied to type `Error`
   --> $DIR/derives-span-PartialEq-enum-struct-variant.rs:9:6
    |
+LL | #[derive(PartialEq)]
+   |          --------- in this derive macro expansion
+...
 LL |      x: Error
    |      ^^^^^^^^
    |
@@ -10,6 +13,9 @@ LL |      x: Error
 error[E0369]: binary operation `!=` cannot be applied to type `Error`
   --> $DIR/derives-span-PartialEq-enum-struct-variant.rs:9:6
    |
+LL | #[derive(PartialEq)]
+   |          --------- in this derive macro expansion
+...
 LL |      x: Error
    |      ^^^^^^^^
    |
index 532430729c7cf3463ed05caa63d0a725778e0c90..cdb40c39f169ce7657f767654dad57b169820ac1 100644 (file)
@@ -1,6 +1,9 @@
 error[E0369]: binary operation `==` cannot be applied to type `Error`
   --> $DIR/derives-span-PartialEq-enum.rs:9:6
    |
+LL | #[derive(PartialEq)]
+   |          --------- in this derive macro expansion
+...
 LL |      Error
    |      ^^^^^
    |
@@ -10,6 +13,9 @@ LL |      Error
 error[E0369]: binary operation `!=` cannot be applied to type `Error`
   --> $DIR/derives-span-PartialEq-enum.rs:9:6
    |
+LL | #[derive(PartialEq)]
+   |          --------- in this derive macro expansion
+...
 LL |      Error
    |      ^^^^^
    |
index 5fec402dcd8565dde5625a2df0955fa8dc16f20d..4cf8851a098bcdb10289e9638e8953b78128ccea 100644 (file)
@@ -1,6 +1,9 @@
 error[E0369]: binary operation `==` cannot be applied to type `Error`
   --> $DIR/derives-span-PartialEq-struct.rs:8:5
    |
+LL | #[derive(PartialEq)]
+   |          --------- in this derive macro expansion
+LL | struct Struct {
 LL |     x: Error
    |     ^^^^^^^^
    |
@@ -10,6 +13,9 @@ LL |     x: Error
 error[E0369]: binary operation `!=` cannot be applied to type `Error`
   --> $DIR/derives-span-PartialEq-struct.rs:8:5
    |
+LL | #[derive(PartialEq)]
+   |          --------- in this derive macro expansion
+LL | struct Struct {
 LL |     x: Error
    |     ^^^^^^^^
    |
index 0a7f9e14859ae94e91c5e9f8ebc615ac4837ed2a..66bc16873538984644b7ec65f93128f87b8c3e8f 100644 (file)
@@ -1,6 +1,9 @@
 error[E0369]: binary operation `==` cannot be applied to type `Error`
   --> $DIR/derives-span-PartialEq-tuple-struct.rs:8:5
    |
+LL | #[derive(PartialEq)]
+   |          --------- in this derive macro expansion
+LL | struct Struct(
 LL |     Error
    |     ^^^^^
    |
@@ -10,6 +13,9 @@ LL |     Error
 error[E0369]: binary operation `!=` cannot be applied to type `Error`
   --> $DIR/derives-span-PartialEq-tuple-struct.rs:8:5
    |
+LL | #[derive(PartialEq)]
+   |          --------- in this derive macro expansion
+LL | struct Struct(
 LL |     Error
    |     ^^^^^
    |
index 8d84b1217b7a371ae3bbc8140d06e177be433baa..9a716048e26aa0a0694bc974b9ef636cb6b33b20 100644 (file)
@@ -1,11 +1,18 @@
 error[E0277]: can't compare `Error` with `Error`
   --> $DIR/derives-span-PartialOrd-enum-struct-variant.rs:9:6
    |
+LL | #[derive(PartialOrd,PartialEq)]
+   |          ---------- in this derive macro expansion
+...
 LL |      x: Error
    |      ^^^^^^^^ no implementation for `Error < Error` and `Error > Error`
    |
    = help: the trait `PartialOrd` is not implemented for `Error`
-   = note: required by `std::cmp::PartialOrd::partial_cmp`
+note: required by `std::cmp::PartialOrd::partial_cmp`
+  --> $SRC_DIR/core/src/cmp.rs:LL:COL
+   |
+LL |     fn partial_cmp(&self, other: &Rhs) -> Option<Ordering>;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: this error originates in the derive macro `PartialOrd` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: aborting due to previous error
index ce12727989df8ad60007a7171a52663f9e868c08..c726d33eab0135ef850f8c547e5b98fbcf0294ce 100644 (file)
@@ -1,11 +1,18 @@
 error[E0277]: can't compare `Error` with `Error`
   --> $DIR/derives-span-PartialOrd-enum.rs:9:6
    |
+LL | #[derive(PartialOrd,PartialEq)]
+   |          ---------- in this derive macro expansion
+...
 LL |      Error
    |      ^^^^^ no implementation for `Error < Error` and `Error > Error`
    |
    = help: the trait `PartialOrd` is not implemented for `Error`
-   = note: required by `std::cmp::PartialOrd::partial_cmp`
+note: required by `std::cmp::PartialOrd::partial_cmp`
+  --> $SRC_DIR/core/src/cmp.rs:LL:COL
+   |
+LL |     fn partial_cmp(&self, other: &Rhs) -> Option<Ordering>;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: this error originates in the derive macro `PartialOrd` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: aborting due to previous error
index fc488e734f752821819bb09830b44725a3b6406c..a56c163ca788ae061cbeff8d8afb601f9559e4d7 100644 (file)
@@ -1,11 +1,18 @@
 error[E0277]: can't compare `Error` with `Error`
   --> $DIR/derives-span-PartialOrd-struct.rs:8:5
    |
+LL | #[derive(PartialOrd,PartialEq)]
+   |          ---------- in this derive macro expansion
+LL | struct Struct {
 LL |     x: Error
    |     ^^^^^^^^ no implementation for `Error < Error` and `Error > Error`
    |
    = help: the trait `PartialOrd` is not implemented for `Error`
-   = note: required by `std::cmp::PartialOrd::partial_cmp`
+note: required by `std::cmp::PartialOrd::partial_cmp`
+  --> $SRC_DIR/core/src/cmp.rs:LL:COL
+   |
+LL |     fn partial_cmp(&self, other: &Rhs) -> Option<Ordering>;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: this error originates in the derive macro `PartialOrd` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: aborting due to previous error
index e18b039f21f26f7ef5c39fed4f627888b6c11cee..7a0a52e582444861a996ec12cc1aba12099cde47 100644 (file)
@@ -1,11 +1,18 @@
 error[E0277]: can't compare `Error` with `Error`
   --> $DIR/derives-span-PartialOrd-tuple-struct.rs:8:5
    |
+LL | #[derive(PartialOrd,PartialEq)]
+   |          ---------- in this derive macro expansion
+LL | struct Struct(
 LL |     Error
    |     ^^^^^ no implementation for `Error < Error` and `Error > Error`
    |
    = help: the trait `PartialOrd` is not implemented for `Error`
-   = note: required by `std::cmp::PartialOrd::partial_cmp`
+note: required by `std::cmp::PartialOrd::partial_cmp`
+  --> $SRC_DIR/core/src/cmp.rs:LL:COL
+   |
+LL |     fn partial_cmp(&self, other: &Rhs) -> Option<Ordering>;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: this error originates in the derive macro `PartialOrd` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: aborting due to previous error
index 4919bac526360df08a5e6711009f95fa558b7d11..09611555fb9a57d0972ca500327170efd6eb1631 100644 (file)
@@ -10,7 +10,12 @@ LL |     is_copy(B { a: 1, b: C });
    |             expected an implementor of trait `Copy`
    |             help: consider borrowing here: `&B { a: 1, b: C }`
    |
-   = note: required because of the requirements on the impl of `Copy` for `B<C>`
+note: required because of the requirements on the impl of `Copy` for `B<C>`
+  --> $DIR/deriving-copyclone.rs:9:10
+   |
+LL | #[derive(Copy, Clone)]
+   |          ^^^^
+   = note: this error originates in the derive macro `Copy` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0277]: the trait bound `C: Clone` is not satisfied
   --> $DIR/deriving-copyclone.rs:32:14
@@ -24,7 +29,12 @@ LL |     is_clone(B { a: 1, b: C });
    |              expected an implementor of trait `Clone`
    |              help: consider borrowing here: `&B { a: 1, b: C }`
    |
-   = note: required because of the requirements on the impl of `Clone` for `B<C>`
+note: required because of the requirements on the impl of `Clone` for `B<C>`
+  --> $DIR/deriving-copyclone.rs:9:16
+   |
+LL | #[derive(Copy, Clone)]
+   |                ^^^^^
+   = note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0277]: the trait bound `D: Copy` is not satisfied
   --> $DIR/deriving-copyclone.rs:35:13
@@ -38,7 +48,12 @@ LL |     is_copy(B { a: 1, b: D });
    |             expected an implementor of trait `Copy`
    |             help: consider borrowing here: `&B { a: 1, b: D }`
    |
-   = note: required because of the requirements on the impl of `Copy` for `B<D>`
+note: required because of the requirements on the impl of `Copy` for `B<D>`
+  --> $DIR/deriving-copyclone.rs:9:10
+   |
+LL | #[derive(Copy, Clone)]
+   |          ^^^^
+   = note: this error originates in the derive macro `Copy` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: aborting due to 3 previous errors
 
index 0f69f94bf3a2a0d8402451b190a0cc76917ebdab..b97f87da4bfce22f357120e0fd88a310c207d411 100644 (file)
@@ -1,6 +1,9 @@
 error[E0369]: binary operation `==` cannot be applied to type `NoCloneOrEq`
   --> $DIR/deriving-no-inner-impl-error-message.rs:5:5
    |
+LL | #[derive(PartialEq)]
+   |          --------- in this derive macro expansion
+LL | struct E {
 LL |     x: NoCloneOrEq
    |     ^^^^^^^^^^^^^^
    |
@@ -10,6 +13,9 @@ LL |     x: NoCloneOrEq
 error[E0369]: binary operation `!=` cannot be applied to type `NoCloneOrEq`
   --> $DIR/deriving-no-inner-impl-error-message.rs:5:5
    |
+LL | #[derive(PartialEq)]
+   |          --------- in this derive macro expansion
+LL | struct E {
 LL |     x: NoCloneOrEq
    |     ^^^^^^^^^^^^^^
    |
@@ -19,10 +25,17 @@ LL |     x: NoCloneOrEq
 error[E0277]: the trait bound `NoCloneOrEq: Clone` is not satisfied
   --> $DIR/deriving-no-inner-impl-error-message.rs:10:5
    |
+LL | #[derive(Clone)]
+   |          ----- in this derive macro expansion
+LL | struct C {
 LL |     x: NoCloneOrEq
    |     ^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `NoCloneOrEq`
    |
-   = note: required by `clone`
+note: required by `clone`
+  --> $SRC_DIR/core/src/clone.rs:LL:COL
+   |
+LL |     fn clone(&self) -> Self;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^
    = note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: aborting due to 3 previous errors
index 7e14c12c0a9920afb94c4322541724228062f6db..9afffa90085908d0d6857bb44efbb4bb20a0f754 100644 (file)
@@ -2,29 +2,29 @@
 
 struct S;
 
-#[derive(PartialEq)] //~ ERROR: `derive` may only be applied to structs, enums and unions
+#[derive(PartialEq)] //~ ERROR: `derive` may only be applied to `struct`s, `enum`s and `union`s
 trait T { }
 
-#[derive(PartialEq)] //~ ERROR: `derive` may only be applied to structs, enums and unions
+#[derive(PartialEq)] //~ ERROR: `derive` may only be applied to `struct`s, `enum`s and `union`s
 impl S { }
 
-#[derive(PartialEq)] //~ ERROR: `derive` may only be applied to structs, enums and unions
+#[derive(PartialEq)] //~ ERROR: `derive` may only be applied to `struct`s, `enum`s and `union`s
 impl T for S { }
 
-#[derive(PartialEq)] //~ ERROR: `derive` may only be applied to structs, enums and unions
+#[derive(PartialEq)] //~ ERROR: `derive` may only be applied to `struct`s, `enum`s and `union`s
 static s: usize = 0;
 
-#[derive(PartialEq)] //~ ERROR: `derive` may only be applied to structs, enums and unions
+#[derive(PartialEq)] //~ ERROR: `derive` may only be applied to `struct`s, `enum`s and `union`s
 const c: usize = 0;
 
-#[derive(PartialEq)] //~ ERROR: `derive` may only be applied to structs, enums and unions
+#[derive(PartialEq)] //~ ERROR: `derive` may only be applied to `struct`s, `enum`s and `union`s
 mod m { }
 
-#[derive(PartialEq)] //~ ERROR: `derive` may only be applied to structs, enums and unions
+#[derive(PartialEq)] //~ ERROR: `derive` may only be applied to `struct`s, `enum`s and `union`s
 extern "C" { }
 
-#[derive(PartialEq)] //~ ERROR: `derive` may only be applied to structs, enums and unions
+#[derive(PartialEq)] //~ ERROR: `derive` may only be applied to `struct`s, `enum`s and `union`s
 type A = usize;
 
-#[derive(PartialEq)] //~ ERROR: `derive` may only be applied to structs, enums and unions
+#[derive(PartialEq)] //~ ERROR: `derive` may only be applied to `struct`s, `enum`s and `union`s
 fn main() { }
index 8c9daf4d4b30bfaed66c5a019a28d7d77810abd1..ef7ef54d1ae6b494d48f0baae983cc38fdfe40a6 100644 (file)
@@ -1,56 +1,74 @@
-error[E0774]: `derive` may only be applied to structs, enums and unions
+error[E0774]: `derive` may only be applied to `struct`s, `enum`s and `union`s
   --> $DIR/deriving-non-type.rs:5:1
    |
 LL | #[derive(PartialEq)]
-   | ^^^^^^^^^^^^^^^^^^^^
+   | ^^^^^^^^^^^^^^^^^^^^ not applicable here
+LL | trait T { }
+   | ----------- not a `struct`, `enum` or `union`
 
-error[E0774]: `derive` may only be applied to structs, enums and unions
+error[E0774]: `derive` may only be applied to `struct`s, `enum`s and `union`s
   --> $DIR/deriving-non-type.rs:8:1
    |
 LL | #[derive(PartialEq)]
-   | ^^^^^^^^^^^^^^^^^^^^
+   | ^^^^^^^^^^^^^^^^^^^^ not applicable here
+LL | impl S { }
+   | ---------- not a `struct`, `enum` or `union`
 
-error[E0774]: `derive` may only be applied to structs, enums and unions
+error[E0774]: `derive` may only be applied to `struct`s, `enum`s and `union`s
   --> $DIR/deriving-non-type.rs:11:1
    |
 LL | #[derive(PartialEq)]
-   | ^^^^^^^^^^^^^^^^^^^^
+   | ^^^^^^^^^^^^^^^^^^^^ not applicable here
+LL | impl T for S { }
+   | ---------------- not a `struct`, `enum` or `union`
 
-error[E0774]: `derive` may only be applied to structs, enums and unions
+error[E0774]: `derive` may only be applied to `struct`s, `enum`s and `union`s
   --> $DIR/deriving-non-type.rs:14:1
    |
 LL | #[derive(PartialEq)]
-   | ^^^^^^^^^^^^^^^^^^^^
+   | ^^^^^^^^^^^^^^^^^^^^ not applicable here
+LL | static s: usize = 0;
+   | -------------------- not a `struct`, `enum` or `union`
 
-error[E0774]: `derive` may only be applied to structs, enums and unions
+error[E0774]: `derive` may only be applied to `struct`s, `enum`s and `union`s
   --> $DIR/deriving-non-type.rs:17:1
    |
 LL | #[derive(PartialEq)]
-   | ^^^^^^^^^^^^^^^^^^^^
+   | ^^^^^^^^^^^^^^^^^^^^ not applicable here
+LL | const c: usize = 0;
+   | ------------------- not a `struct`, `enum` or `union`
 
-error[E0774]: `derive` may only be applied to structs, enums and unions
+error[E0774]: `derive` may only be applied to `struct`s, `enum`s and `union`s
   --> $DIR/deriving-non-type.rs:20:1
    |
 LL | #[derive(PartialEq)]
-   | ^^^^^^^^^^^^^^^^^^^^
+   | ^^^^^^^^^^^^^^^^^^^^ not applicable here
+LL | mod m { }
+   | --------- not a `struct`, `enum` or `union`
 
-error[E0774]: `derive` may only be applied to structs, enums and unions
+error[E0774]: `derive` may only be applied to `struct`s, `enum`s and `union`s
   --> $DIR/deriving-non-type.rs:23:1
    |
 LL | #[derive(PartialEq)]
-   | ^^^^^^^^^^^^^^^^^^^^
+   | ^^^^^^^^^^^^^^^^^^^^ not applicable here
+LL | extern "C" { }
+   | -------------- not a `struct`, `enum` or `union`
 
-error[E0774]: `derive` may only be applied to structs, enums and unions
+error[E0774]: `derive` may only be applied to `struct`s, `enum`s and `union`s
   --> $DIR/deriving-non-type.rs:26:1
    |
 LL | #[derive(PartialEq)]
-   | ^^^^^^^^^^^^^^^^^^^^
+   | ^^^^^^^^^^^^^^^^^^^^ not applicable here
+LL | type A = usize;
+   | --------------- not a `struct`, `enum` or `union`
 
-error[E0774]: `derive` may only be applied to structs, enums and unions
+error[E0774]: `derive` may only be applied to `struct`s, `enum`s and `union`s
   --> $DIR/deriving-non-type.rs:29:1
    |
 LL | #[derive(PartialEq)]
-   | ^^^^^^^^^^^^^^^^^^^^
+   | ^^^^^^^^^^^^^^^^^^^^ not applicable here
+LL | fn main() { }
+   | ------------- not a `struct`, `enum` or `union`
 
 error: aborting due to 9 previous errors
 
index 1bd4543f2316c5bfab5d4a9ff7d4847931dc7d40..fcb4ea1d592b589d81bbeb0a174890e993335348 100644 (file)
@@ -1,9 +1,6 @@
 error[E0277]: the trait bound `i8: Foo<i32>` is not satisfied
   --> $DIR/issue-39802-show-5-trait-impls.rs:24:21
    |
-LL |     fn bar(&self){}
-   |     ------------- required by `Foo::bar`
-...
 LL |     Foo::<i32>::bar(&1i8);
    |                     ^^^^ the trait `Foo<i32>` is not implemented for `i8`
    |
@@ -13,13 +10,15 @@ LL |     Foo::<i32>::bar(&1i8);
              <i8 as Foo<u32>>
              <i8 as Foo<u64>>
              <i8 as Foo<u8>>
+note: required by `Foo::bar`
+  --> $DIR/issue-39802-show-5-trait-impls.rs:2:5
+   |
+LL |     fn bar(&self){}
+   |     ^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `u8: Foo<i32>` is not satisfied
   --> $DIR/issue-39802-show-5-trait-impls.rs:25:21
    |
-LL |     fn bar(&self){}
-   |     ------------- required by `Foo::bar`
-...
 LL |     Foo::<i32>::bar(&1u8);
    |                     ^^^^ the trait `Foo<i32>` is not implemented for `u8`
    |
@@ -28,13 +27,15 @@ LL |     Foo::<i32>::bar(&1u8);
              <u8 as Foo<u16>>
              <u8 as Foo<u32>>
              <u8 as Foo<u64>>
+note: required by `Foo::bar`
+  --> $DIR/issue-39802-show-5-trait-impls.rs:2:5
+   |
+LL |     fn bar(&self){}
+   |     ^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `bool: Foo<i32>` is not satisfied
   --> $DIR/issue-39802-show-5-trait-impls.rs:26:21
    |
-LL |     fn bar(&self){}
-   |     ------------- required by `Foo::bar`
-...
 LL |     Foo::<i32>::bar(&true);
    |                     ^^^^^ the trait `Foo<i32>` is not implemented for `bool`
    |
@@ -44,6 +45,11 @@ LL |     Foo::<i32>::bar(&true);
              <bool as Foo<u16>>
              <bool as Foo<u32>>
            and 2 others
+note: required by `Foo::bar`
+  --> $DIR/issue-39802-show-5-trait-impls.rs:2:5
+   |
+LL |     fn bar(&self){}
+   |     ^^^^^^^^^^^^^
 
 error: aborting due to 3 previous errors
 
index 559f10de109815b0492d7548d75b95dfb3fac98d..d8553815b75de11cbd209aa915e947983cfd9426 100644 (file)
@@ -1,12 +1,14 @@
 #![feature(imported_main)]
-#![feature(min_type_alias_impl_trait, impl_trait_in_bindings)]
+#![feature(min_type_alias_impl_trait)]
 #![allow(incomplete_features)]
 //~^^^ ERROR `main` function not found in crate
 pub mod foo {
     type MainFn = impl Fn();
+    //~^ ERROR could not find defining uses
 
     fn bar() {}
     pub const BAR: MainFn = bar;
+    //~^ ERROR mismatched types [E0308]
 }
 
 use foo::BAR as main;
index 9b879fc09f7290c3e06d97f0bb32dc3587c19ead..c4c0afc5687c1aa99bf4e6ee112a91836846401d 100644 (file)
@@ -2,7 +2,7 @@ error[E0601]: `main` function not found in crate `imported_main_const_fn_item_ty
   --> $DIR/imported_main_const_fn_item_type_forbidden.rs:1:1
    |
 LL | / #![feature(imported_main)]
-LL | | #![feature(min_type_alias_impl_trait, impl_trait_in_bindings)]
+LL | | #![feature(min_type_alias_impl_trait)]
 LL | | #![allow(incomplete_features)]
 LL | |
 ...  |
@@ -12,6 +12,25 @@ LL | | use foo::BAR as main;
    |       |
    |       non-function item at `crate::main` is found
 
-error: aborting due to previous error
+error[E0308]: mismatched types
+  --> $DIR/imported_main_const_fn_item_type_forbidden.rs:10:29
+   |
+LL |     type MainFn = impl Fn();
+   |                   --------- the expected opaque type
+...
+LL |     pub const BAR: MainFn = bar;
+   |                             ^^^ expected opaque type, found fn item
+   |
+   = note: expected opaque type `impl Fn<()>`
+                  found fn item `fn() {bar}`
+
+error: could not find defining uses
+  --> $DIR/imported_main_const_fn_item_type_forbidden.rs:6:19
+   |
+LL |     type MainFn = impl Fn();
+   |                   ^^^^^^^^^
+
+error: aborting due to 3 previous errors
 
-For more information about this error, try `rustc --explain E0601`.
+Some errors have detailed explanations: E0308, E0601.
+For more information about an error, try `rustc --explain E0308`.
index eb68a6298d1ac1217a3deca57ec8d270478359df..cead9776e4abb3a4a4d96319cbc747a6d84df428 100644 (file)
@@ -1,8 +1,8 @@
 error[E0038]: the trait `Trait` cannot be made into an object
-  --> $DIR/E0038.rs:5:16
+  --> $DIR/E0038.rs:5:20
    |
 LL | fn call_foo(x: Box<dyn Trait>) {
-   |                ^^^^^^^^^^^^^^ `Trait` cannot be made into an object
+   |                    ^^^^^^^^^ `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>
index 2f0dfb6dd8248e8093fb75036b175f9b4fdb4863..b6078e302360612b8f7c218c8942345c99b57957 100644 (file)
@@ -1,13 +1,15 @@
 error[E0283]: type annotations needed
   --> $DIR/E0283.rs:30:21
    |
-LL |     fn create() -> u32;
-   |     ------------------- required by `Generator::create`
-...
 LL |     let cont: u32 = Generator::create();
    |                     ^^^^^^^^^^^^^^^^^ cannot infer type
    |
    = note: cannot satisfy `_: Generator`
+note: required by `Generator::create`
+  --> $DIR/E0283.rs:2:5
+   |
+LL |     fn create() -> u32;
+   |     ^^^^^^^^^^^^^^^^^^^
 
 error[E0283]: type annotations needed
   --> $DIR/E0283.rs:35:24
index 1d3336fb181a06778af862ecf457850ae2f1c893..e59b8a8ae35ac1bf3b854b4ac1286eadf274c2fc 100644 (file)
@@ -1,6 +1,9 @@
 error[E0624]: associated function `method` is private
   --> $DIR/E0624.rs:11:9
    |
+LL |         fn method(&self) {}
+   |         ---------------- private associated function defined here
+...
 LL |     foo.method();
    |         ^^^^^^ private associated function
 
index ea73c58993e2b70fee65eaa5967186d38ff2d48a..14697d89e822bb6d1eeb6cbabf51aaa4f5a67fdc 100644 (file)
@@ -2,7 +2,7 @@ error[E0777]: expected path to a trait, found literal
   --> $DIR/E0777.rs:1:10
    |
 LL | #[derive("Clone")]
-   |          ^^^^^^^
+   |          ^^^^^^^ not a trait
    |
    = help: try using `#[derive(Clone)]`
 
@@ -12,7 +12,7 @@ error[E0777]: expected path to a trait, found literal
 LL |   #[derive("Clone
    |  __________^
 LL | | ")]
-   | |_^
+   | |_^ not a trait
    |
    = help: for example, write `#[derive(Debug)]` for `Debug`
 
index 55f43840b9a3ad6a87a94e10292e5da941b2745f..f4a2330da177381d8e4dd887d5dbe68f629d3170 100644 (file)
@@ -84,18 +84,33 @@ error[E0624]: associated function `pub_crate` is private
    |
 LL |     r.pub_crate();
    |       ^^^^^^^^^ private associated function
+   | 
+  ::: $DIR/auxiliary/pub-and-stability.rs:114:9
+   |
+LL |         pub(crate) fn pub_crate(&self) -> i32 { self.d_priv }
+   |         ------------------------------------- private associated function defined here
 
 error[E0624]: associated function `pub_mod` is private
   --> $DIR/explore-issue-38412.rs:51:7
    |
 LL |     r.pub_mod();
    |       ^^^^^^^ private associated function
+   | 
+  ::: $DIR/auxiliary/pub-and-stability.rs:116:9
+   |
+LL |         pub(in m) fn pub_mod(&self) -> i32 { self.d_priv }
+   |         ---------------------------------- private associated function defined here
 
 error[E0624]: associated function `private` is private
   --> $DIR/explore-issue-38412.rs:52:7
    |
 LL |     r.private();
    |       ^^^^^^^ private associated function
+   | 
+  ::: $DIR/auxiliary/pub-and-stability.rs:118:9
+   |
+LL |         fn private(&self) -> i32 { self.d_priv }
+   |         ------------------------ private associated function defined here
 
 error[E0658]: use of unstable library feature 'unstable_undeclared'
   --> $DIR/explore-issue-38412.rs:57:7
@@ -120,18 +135,33 @@ error[E0624]: associated function `pub_crate` is private
    |
 LL |     t.pub_crate();
    |       ^^^^^^^^^ private associated function
+   | 
+  ::: $DIR/auxiliary/pub-and-stability.rs:129:9
+   |
+LL |         pub(crate) fn pub_crate(&self) -> i32 { self.0 }
+   |         ------------------------------------- private associated function defined here
 
 error[E0624]: associated function `pub_mod` is private
   --> $DIR/explore-issue-38412.rs:64:7
    |
 LL |     t.pub_mod();
    |       ^^^^^^^ private associated function
+   | 
+  ::: $DIR/auxiliary/pub-and-stability.rs:130:9
+   |
+LL |         pub(in m) fn pub_mod(&self) -> i32 { self.0 }
+   |         ---------------------------------- private associated function defined here
 
 error[E0624]: associated function `private` is private
   --> $DIR/explore-issue-38412.rs:65:7
    |
 LL |     t.private();
    |       ^^^^^^^ private associated function
+   | 
+  ::: $DIR/auxiliary/pub-and-stability.rs:131:9
+   |
+LL |         fn private(&self) -> i32 { self.0 }
+   |         ------------------------ private associated function defined here
 
 error: aborting due to 19 previous errors
 
index 38be85ff8201ed77a5840269e0acacd6ef558284..1e48996acb83346f9cd4390423146d6b2601a428 100644 (file)
@@ -57,20 +57,20 @@ fn _rpit_dyn() -> Box<dyn Tr1<As1: Copy>> { Box::new(S1) }
 
 const _cdef: impl Tr1<As1: Copy> = S1;
 //~^ ERROR associated type bounds are unstable
-//~| ERROR `impl Trait` not allowed outside of function and inherent method return types [E0562]
+//~| ERROR `impl Trait` not allowed outside of function and method return types [E0562]
 // FIXME: uncomment when `impl_trait_in_bindings` feature is fixed.
 // const _cdef_dyn: &dyn Tr1<As1: Copy> = &S1;
 
 static _sdef: impl Tr1<As1: Copy> = S1;
 //~^ ERROR associated type bounds are unstable
-//~| ERROR `impl Trait` not allowed outside of function and inherent method return types [E0562]
+//~| ERROR `impl Trait` not allowed outside of function and method return types [E0562]
 // FIXME: uncomment when `impl_trait_in_bindings` feature is fixed.
 // static _sdef_dyn: &dyn Tr1<As1: Copy> = &S1;
 
 fn main() {
     let _: impl Tr1<As1: Copy> = S1;
     //~^ ERROR associated type bounds are unstable
-    //~| ERROR `impl Trait` not allowed outside of function and inherent method return types [E0562]
+    //~| ERROR `impl Trait` not allowed outside of function and method return types [E0562]
     // FIXME: uncomment when `impl_trait_in_bindings` feature is fixed.
     // let _: &dyn Tr1<As1: Copy> = &S1;
 }
index be5d35139b65c7db978aa46e1301d24f32071d65..2dacb94bcc07a7dad743f01c0b6674f888abec0a 100644 (file)
@@ -115,29 +115,23 @@ LL |     let _: impl Tr1<As1: Copy> = S1;
    = note: see issue #52662 <https://github.com/rust-lang/rust/issues/52662> for more information
    = help: add `#![feature(associated_type_bounds)]` to the crate attributes to enable
 
-error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+error[E0562]: `impl Trait` not allowed outside of function and method return types
   --> $DIR/feature-gate-associated_type_bounds.rs:58:14
    |
 LL | const _cdef: impl Tr1<As1: Copy> = S1;
    |              ^^^^^^^^^^^^^^^^^^^
-   |
-   = help: add `#![feature(impl_trait_in_bindings)]` to the crate attributes to enable
 
-error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+error[E0562]: `impl Trait` not allowed outside of function and method return types
   --> $DIR/feature-gate-associated_type_bounds.rs:64:15
    |
 LL | static _sdef: impl Tr1<As1: Copy> = S1;
    |               ^^^^^^^^^^^^^^^^^^^
-   |
-   = help: add `#![feature(impl_trait_in_bindings)]` to the crate attributes to enable
 
-error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+error[E0562]: `impl Trait` not allowed outside of function and method return types
   --> $DIR/feature-gate-associated_type_bounds.rs:71:12
    |
 LL |     let _: impl Tr1<As1: Copy> = S1;
    |            ^^^^^^^^^^^^^^^^^^^
-   |
-   = help: add `#![feature(impl_trait_in_bindings)]` to the crate attributes to enable
 
 error[E0277]: the trait bound `<<Self as _Tr3>::A as Iterator>::Item: Copy` is not satisfied
   --> $DIR/feature-gate-associated_type_bounds.rs:15:28
diff --git a/src/test/ui/feature-gates/feature-gate-impl_trait_in_bindings.rs b/src/test/ui/feature-gates/feature-gate-impl_trait_in_bindings.rs
deleted file mode 100644 (file)
index 39cc64f..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-const FOO: impl Copy = 42;
-//~^ ERROR `impl Trait` not allowed
-
-static BAR: impl Copy = 42;
-//~^ ERROR `impl Trait` not allowed
-
-fn main() {
-    let foo = impl Copy = 42;
-//~^ ERROR expected expression, found keyword `impl`
-    let foo: impl Copy = 42;
-}
diff --git a/src/test/ui/feature-gates/feature-gate-impl_trait_in_bindings.stderr b/src/test/ui/feature-gates/feature-gate-impl_trait_in_bindings.stderr
deleted file mode 100644 (file)
index bd648b4..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-error: expected expression, found keyword `impl`
-  --> $DIR/feature-gate-impl_trait_in_bindings.rs:8:15
-   |
-LL |     let foo = impl Copy = 42;
-   |               ^^^^ expected expression
-
-error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
-  --> $DIR/feature-gate-impl_trait_in_bindings.rs:1:12
-   |
-LL | const FOO: impl Copy = 42;
-   |            ^^^^^^^^^
-   |
-   = help: add `#![feature(impl_trait_in_bindings)]` to the crate attributes to enable
-
-error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
-  --> $DIR/feature-gate-impl_trait_in_bindings.rs:4:13
-   |
-LL | static BAR: impl Copy = 42;
-   |             ^^^^^^^^^
-   |
-   = help: add `#![feature(impl_trait_in_bindings)]` to the crate attributes to enable
-
-error: aborting due to 3 previous errors
-
-For more information about this error, try `rustc --explain E0562`.
index b82867c67025a398e283e9776b4d5499642bf542..07857289aaeb55a34488bdbd049e110f80153a62 100644 (file)
@@ -106,7 +106,7 @@ LL |     type Baa = (Vec<impl Debug>, impl Debug, impl Iterator<Item = impl Debu
    = note: see issue #63063 <https://github.com/rust-lang/rust/issues/63063> for more information
    = help: add `#![feature(min_type_alias_impl_trait)]` to the crate attributes to enable
 
-error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+error[E0562]: `impl Trait` not allowed outside of function and method return types
   --> $DIR/feature-gate-min_type_alias_impl_trait.rs:23:18
    |
 LL |     type Assoc = impl Debug;
index 12195bc1071a08144f9eb6851e0eb96a63a8e2d4..c13c05f146a7e676f94dadf53f7ca31eb8b773a9 100644 (file)
@@ -1,8 +1,8 @@
 error[E0038]: the trait `NonObjectSafe1` cannot be made into an object
-  --> $DIR/feature-gate-object_safe_for_dispatch.rs:18:38
+  --> $DIR/feature-gate-object_safe_for_dispatch.rs:18:39
    |
 LL | fn takes_non_object_safe_ref<T>(obj: &dyn NonObjectSafe1) {
-   |                                      ^^^^^^^^^^^^^^^^^^^ `NonObjectSafe1` cannot be made into an object
+   |                                       ^^^^^^^^^^^^^^^^^^ `NonObjectSafe1` 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/feature-gate-object_safe_for_dispatch.rs:4:23
@@ -35,10 +35,10 @@ LL |     fn static_fn() where Self: Sized {}
    |                    ^^^^^^^^^^^^^^^^^
 
 error[E0038]: the trait `NonObjectSafe3` cannot be made into an object
-  --> $DIR/feature-gate-object_safe_for_dispatch.rs:27:35
+  --> $DIR/feature-gate-object_safe_for_dispatch.rs:27:39
    |
 LL | fn takes_non_object_safe_box(obj: Box<dyn NonObjectSafe3>) {
-   |                                   ^^^^^^^^^^^^^^^^^^^^^^^ `NonObjectSafe3` cannot be made into an object
+   |                                       ^^^^^^^^^^^^^^^^^^ `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>
index 50ce6427e8b584cd497a51e58f7c5768d1514310..a3ced35155f370a465449d788fe91e75202c83aa 100644 (file)
@@ -51,4 +51,5 @@ LL | #[optimize(banana)]
 
 error: aborting due to 6 previous errors
 
-For more information about this error, try `rustc --explain E0658`.
+Some errors have detailed explanations: E0658, E0722.
+For more information about an error, try `rustc --explain E0658`.
index dfd82a25f4c8757750cca9c99d0214a9669d0b60..4fb1cd2aae1d311c7bd1b9b7d846a0ca153f1db2 100644 (file)
@@ -31,7 +31,7 @@ fn define3_1() {
 
 fn define4() {
     let y: Foo4 = 42;
-    //~^ ERROR not permitted here
+    //~^ ERROR mismatched types [E0308]
 }
 
 fn main() {}
index 43fd76ef0ed9fe2e0d6546750d0ab1ffb35ecad1..10409d5fc4badabbe492f53fbf79ef4454fc730a 100644 (file)
@@ -45,14 +45,19 @@ LL |     define3(42)
    = note: expected opaque type `impl Debug`
                      found type `{integer}`
 
-error[E0658]: type alias impl trait is not permitted here
-  --> $DIR/feature-gate-type_alias_impl_trait.rs:33:12
+error[E0308]: mismatched types
+  --> $DIR/feature-gate-type_alias_impl_trait.rs:33:19
    |
+LL | type Foo4 = impl Debug;
+   |             ---------- the expected opaque type
+...
 LL |     let y: Foo4 = 42;
-   |            ^^^^
+   |            ----   ^^ expected opaque type, found integer
+   |            |
+   |            expected due to this
    |
-   = note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
-   = help: add `#![feature(impl_trait_in_bindings)]` to the crate attributes to enable
+   = note: expected opaque type `impl Debug`
+                     found type `{integer}`
 
 error: could not find defining uses
   --> $DIR/feature-gate-type_alias_impl_trait.rs:5:12
index 5404b8c04bb76e0b40677fe84b1a426919be8cd6..86a352251b2020599743f0cd4fec020c20f4c9e7 100644 (file)
@@ -2,14 +2,14 @@
 // definitions.
 
 #[derive(Debug)]
-//~^ ERROR `derive` may only be applied to structs, enums and unions
+//~^ ERROR `derive` may only be applied to `struct`s, `enum`s and `union`s
 mod derive {
     mod inner { #![derive(Debug)] }
-    //~^ ERROR `derive` may only be applied to structs, enums and unions
+    //~^ ERROR `derive` may only be applied to `struct`s, `enum`s and `union`s
     //~| ERROR inner macro attributes are unstable
 
     #[derive(Debug)]
-    //~^ ERROR `derive` may only be applied to structs, enums and unions
+    //~^ ERROR `derive` may only be applied to `struct`s, `enum`s and `union`s
     fn derive() { }
 
     #[derive(Copy, Clone)] // (can't derive Debug for unions)
@@ -22,11 +22,11 @@ union U { f: i32 }
     enum E { }
 
     #[derive(Debug)]
-    //~^ ERROR `derive` may only be applied to structs, enums and unions
+    //~^ ERROR `derive` may only be applied to `struct`s, `enum`s and `union`s
     type T = S;
 
     #[derive(Debug)]
-    //~^ ERROR `derive` may only be applied to structs, enums and unions
+    //~^ ERROR `derive` may only be applied to `struct`s, `enum`s and `union`s
     impl S { }
 }
 
index 9b1f4f46219d2e85f964709d16a1b7685b689b9e..bb8651ffb0955778c0d78a5689ca2e025da17e57 100644 (file)
@@ -1,8 +1,17 @@
-error[E0774]: `derive` may only be applied to structs, enums and unions
+error[E0774]: `derive` may only be applied to `struct`s, `enum`s and `union`s
   --> $DIR/issue-43106-gating-of-derive.rs:4:1
    |
-LL | #[derive(Debug)]
-   | ^^^^^^^^^^^^^^^^
+LL |   #[derive(Debug)]
+   |   ^^^^^^^^^^^^^^^^ not applicable here
+LL |
+LL | / mod derive {
+LL | |     mod inner { #![derive(Debug)] }
+LL | |
+LL | |
+...  |
+LL | |     impl S { }
+LL | | }
+   | |_- not a `struct`, `enum` or `union`
 
 error[E0658]: inner macro attributes are unstable
   --> $DIR/issue-43106-gating-of-derive.rs:7:20
@@ -13,29 +22,41 @@ LL |     mod inner { #![derive(Debug)] }
    = note: see issue #54726 <https://github.com/rust-lang/rust/issues/54726> for more information
    = help: add `#![feature(custom_inner_attributes)]` to the crate attributes to enable
 
-error[E0774]: `derive` may only be applied to structs, enums and unions
+error[E0774]: `derive` may only be applied to `struct`s, `enum`s and `union`s
   --> $DIR/issue-43106-gating-of-derive.rs:7:17
    |
 LL |     mod inner { #![derive(Debug)] }
-   |                 ^^^^^^^^^^^^^^^^^
+   |     ------------^^^^^^^^^^^^^^^^^--
+   |     |           |
+   |     |           not applicable here
+   |     not a `struct`, `enum` or `union`
 
-error[E0774]: `derive` may only be applied to structs, enums and unions
+error[E0774]: `derive` may only be applied to `struct`s, `enum`s and `union`s
   --> $DIR/issue-43106-gating-of-derive.rs:11:5
    |
 LL |     #[derive(Debug)]
-   |     ^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^ not applicable here
+LL |
+LL |     fn derive() { }
+   |     --------------- not a `struct`, `enum` or `union`
 
-error[E0774]: `derive` may only be applied to structs, enums and unions
+error[E0774]: `derive` may only be applied to `struct`s, `enum`s and `union`s
   --> $DIR/issue-43106-gating-of-derive.rs:24:5
    |
 LL |     #[derive(Debug)]
-   |     ^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^ not applicable here
+LL |
+LL |     type T = S;
+   |     ----------- not a `struct`, `enum` or `union`
 
-error[E0774]: `derive` may only be applied to structs, enums and unions
+error[E0774]: `derive` may only be applied to `struct`s, `enum`s and `union`s
   --> $DIR/issue-43106-gating-of-derive.rs:28:5
    |
 LL |     #[derive(Debug)]
-   |     ^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^ not applicable here
+LL |
+LL |     impl S { }
+   |     ---------- not a `struct`, `enum` or `union`
 
 error: aborting due to 6 previous errors
 
index 0b401942c4792661797020c75891bf05be36a239..0c30c9dc50c0d8ecd206482d9ed766bc57108629 100644 (file)
@@ -6,3 +6,4 @@ LL |     #[ffi_pure]
 
 error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0757`.
index 05305e12c04027c1cf240ed5d7edffc8de27c5a1..0a68c24b6067cdfa2b41f6be87f541d2a1657aab 100644 (file)
@@ -5,7 +5,11 @@ LL |     format!("{:X}", "3");
    |                     ^^^ the trait `UpperHex` is not implemented for `str`
    |
    = note: required because of the requirements on the impl of `UpperHex` for `&str`
-   = note: required by `std::fmt::UpperHex::fmt`
+note: required by `std::fmt::UpperHex::fmt`
+  --> $SRC_DIR/core/src/fmt/mod.rs:LL:COL
+   |
+LL |     fn fmt(&self, f: &mut Formatter<'_>) -> Result;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: this error originates in the macro `$crate::__export::format_args` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: aborting due to previous error
index 18e46e1d7ded73b0320982a3b6ef3e36def7e344..7eac8c9c5a8df12fabbb531da3fe5942dfc9494e 100644 (file)
@@ -6,7 +6,11 @@ LL |     for c in "asdf" {
    |
    = help: the trait `Iterator` is not implemented for `&str`
    = note: required because of the requirements on the impl of `IntoIterator` for `&str`
-   = note: required by `into_iter`
+note: required by `into_iter`
+  --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
+   |
+LL |     fn into_iter(self) -> Self::IntoIter;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
index 0d9409626897fb35ba12899221f743195f9e6529..288243325c48c412064798a85a89becb012a869c 100644 (file)
@@ -6,7 +6,11 @@ LL |     for x in bogus {
    |
    = help: the trait `Iterator` is not implemented for `MyStruct`
    = note: required because of the requirements on the impl of `IntoIterator` for `MyStruct`
-   = note: required by `into_iter`
+note: required by `into_iter`
+  --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
+   |
+LL |     fn into_iter(self) -> Self::IntoIter;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
index 805a4d1d000cd86f22ff693518825d10de7924ca..bf647d089833a69dd7da2e15ca3beda47261afc3 100644 (file)
@@ -1,26 +1,18 @@
 error[E0425]: cannot find value `Foo` in this scope
-  --> $DIR/layout-error.rs:25:17
+  --> $DIR/layout-error.rs:24:17
    |
 LL |         let a = Foo;
    |                 ^^^ not found in this scope
 
-warning: the feature `impl_trait_in_bindings` is incomplete and may not be safe to use and/or cause compiler crashes
+warning: the feature `type_alias_impl_trait` is incomplete and may not be safe to use and/or cause compiler crashes
   --> $DIR/layout-error.rs:8:32
    |
-LL | #![cfg_attr(full_tait, feature(impl_trait_in_bindings, type_alias_impl_trait))]
-   |                                ^^^^^^^^^^^^^^^^^^^^^^
+LL | #![cfg_attr(full_tait, feature(type_alias_impl_trait))]
+   |                                ^^^^^^^^^^^^^^^^^^^^^
    |
    = note: `#[warn(incomplete_features)]` on by default
-   = note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
-
-warning: the feature `type_alias_impl_trait` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/layout-error.rs:8:56
-   |
-LL | #![cfg_attr(full_tait, feature(impl_trait_in_bindings, type_alias_impl_trait))]
-   |                                                        ^^^^^^^^^^^^^^^^^^^^^
-   |
    = note: see issue #63063 <https://github.com/rust-lang/rust/issues/63063> for more information
 
-error: aborting due to previous error; 2 warnings emitted
+error: aborting due to previous error; 1 warning emitted
 
 For more information about this error, try `rustc --explain E0425`.
index be469d781b5c62f388fdd3730fa353aede322919..ed31c260cbc0f95a04698f6eff880c3935206994 100644 (file)
@@ -1,11 +1,11 @@
 error[E0425]: cannot find value `Foo` in this scope
-  --> $DIR/layout-error.rs:25:17
+  --> $DIR/layout-error.rs:24:17
    |
 LL |         let a = Foo;
    |                 ^^^ not found in this scope
 
 error[E0658]: type alias impl trait is not permitted here
-  --> $DIR/layout-error.rs:31:27
+  --> $DIR/layout-error.rs:30:27
    |
 LL |     Task::spawn(&POOL, || cb());
    |                           ^
@@ -13,28 +13,7 @@ LL |     Task::spawn(&POOL, || cb());
    = note: see issue #63063 <https://github.com/rust-lang/rust/issues/63063> for more information
    = help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable
 
-error[E0658]: type alias impl trait is not permitted here
-  --> $DIR/layout-error.rs:30:28
-   |
-LL |     static POOL: Task<F> = Task::new();
-   |                            ^^^^^^^^^^^
-   |
-   = note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
-   = help: add `#![feature(impl_trait_in_bindings)]` to the crate attributes to enable
-
-error: concrete type differs from previous defining opaque type use
-  --> $DIR/layout-error.rs:31:24
-   |
-LL |     Task::spawn(&POOL, || cb());
-   |                        ^^^^^^^ expected `[type error]`, got `impl Future`
-   |
-note: previous use here
-  --> $DIR/layout-error.rs:30:5
-   |
-LL |     static POOL: Task<F> = Task::new();
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: aborting due to 4 previous errors
+error: aborting due to 2 previous errors
 
 Some errors have detailed explanations: E0425, E0658.
 For more information about an error, try `rustc --explain E0425`.
index 9f15a6b2eca0011c50aeddc850abef9c090271e8..a5efc3899dd4d8538ab889764e1890ef1a1241c3 100644 (file)
@@ -5,9 +5,8 @@
 
 // revisions: min_tait full_tait
 #![feature(min_type_alias_impl_trait)]
-#![cfg_attr(full_tait, feature(impl_trait_in_bindings, type_alias_impl_trait))]
+#![cfg_attr(full_tait, feature(type_alias_impl_trait))]
 //[full_tait]~^ WARN incomplete
-//[full_tait]~| WARN incomplete
 use std::future::Future;
 
 pub struct Task<F: Future>(F);
@@ -27,7 +26,6 @@ async fn cb() {
 
     type F = impl Future;
     // Check that statics are inhabited computes they layout.
-    static POOL: Task<F> = Task::new(); //[min_tait]~ ERROR not permitted here
+    static POOL: Task<F> = Task::new();
     Task::spawn(&POOL, || cb()); //[min_tait]~ ERROR type alias impl trait is not permitted here
-    //[min_tait]~^ ERROR concrete type differs from previous
 }
index ce874c1518c0e15e42f7e7d91b1edfced3099212..1e609e8388277042708681aac897eecfa3fd5cd1 100644 (file)
@@ -1,25 +1,17 @@
 warning: the feature `type_alias_impl_trait` is incomplete and may not be safe to use and/or cause compiler crashes
   --> $DIR/metadata-sufficient-for-layout.rs:10:32
    |
-LL | #![cfg_attr(full_tait, feature(type_alias_impl_trait, impl_trait_in_bindings))]
+LL | #![cfg_attr(full_tait, feature(type_alias_impl_trait))]
    |                                ^^^^^^^^^^^^^^^^^^^^^
    |
    = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #63063 <https://github.com/rust-lang/rust/issues/63063> for more information
 
-warning: the feature `impl_trait_in_bindings` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/metadata-sufficient-for-layout.rs:10:55
-   |
-LL | #![cfg_attr(full_tait, feature(type_alias_impl_trait, impl_trait_in_bindings))]
-   |                                                       ^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
-
 error: fatal error triggered by #[rustc_error]
-  --> $DIR/metadata-sufficient-for-layout.rs:29:1
+  --> $DIR/metadata-sufficient-for-layout.rs:28:1
    |
 LL | fn main() {}
    | ^^^^^^^^^
 
-error: aborting due to previous error; 2 warnings emitted
+error: aborting due to previous error; 1 warning emitted
 
index e2b0d3622a6000231df82f07412ff28de922ea60..52d42fd59a003a1fa8c807241cdc131ce705a043 100644 (file)
@@ -1,24 +1,8 @@
-error[E0658]: type alias impl trait is not permitted here
-  --> $DIR/metadata-sufficient-for-layout.rs:22:23
+error: fatal error triggered by #[rustc_error]
+  --> $DIR/metadata-sufficient-for-layout.rs:28:1
    |
-LL | static A: Option<F> = None;
-   |                       ^^^^
-   |
-   = note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
-   = help: add `#![feature(impl_trait_in_bindings)]` to the crate attributes to enable
-
-error: concrete type differs from previous defining opaque type use
-  --> $DIR/metadata-sufficient-for-layout.rs:25:1
-   |
-LL | fn f() -> F { metadata_sufficient_for_layout::g() }
-   | ^^^^^^^^^^^ expected `[type error]`, got `impl Generator`
-   |
-note: previous use here
-  --> $DIR/metadata-sufficient-for-layout.rs:22:1
-   |
-LL | static A: Option<F> = None;
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | fn main() {}
+   | ^^^^^^^^^
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0658`.
index f206093d9710c23e5ea984ff938b8dfb50690358..c01354569f07d408a6aca5cb0fd9024b2df33475 100644 (file)
@@ -7,9 +7,8 @@
 
 // revisions: min_tait full_tait
 #![feature(min_type_alias_impl_trait, rustc_attrs)]
-#![cfg_attr(full_tait, feature(type_alias_impl_trait, impl_trait_in_bindings))]
+#![cfg_attr(full_tait, feature(type_alias_impl_trait))]
 //[full_tait]~^ WARN incomplete
-//[full_tait]~| WARN incomplete
 #![feature(generator_trait)]
 
 extern crate metadata_sufficient_for_layout;
 
 // Static queries the layout of the generator.
 static A: Option<F> = None;
-//[min_tait]~^ ERROR not permitted here
 
-fn f() -> F { metadata_sufficient_for_layout::g() }
-//[min_tait]~^ ERROR concrete type differs
+fn f() -> F {
+    metadata_sufficient_for_layout::g()
+}
 
 #[rustc_error]
-fn main() {} //[full_tait]~ ERROR
+fn main() {} //~ ERROR
index f0c7cb0e5d50c305fdad3f45b1620368f2f1a082..dff743bc35b2dafd67d0decd1966f9ec7d8d84b1 100644 (file)
@@ -13,7 +13,11 @@ LL |     yield || for i in 0 { }
    = help: the trait `Iterator` is not implemented for `{integer}`
    = note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end`
    = note: required because of the requirements on the impl of `IntoIterator` for `{integer}`
-   = note: required by `into_iter`
+note: required by `into_iter`
+  --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
+   |
+LL |     fn into_iter(self) -> Self::IntoIter;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 2 previous errors
 
index eb8e101a83d799cbae56e5eec1ac0965c47bb797..8651789688eaa75d4f850b00e1a19382a6f23eb3 100644 (file)
@@ -1,8 +1,8 @@
 error[E0038]: the trait `Foo` cannot be made into an object
-  --> $DIR/gat-in-trait-path.rs:21:13
+  --> $DIR/gat-in-trait-path.rs:21:17
    |
 LL | fn f(_arg : Box<dyn for<'a> Foo<A<'a> = &'a ()>>) {}
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Foo` cannot be made into an object
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `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>
index b80b7cf519bce4d97ce02487f855439fa08b00c5..585ba16a491b7b5b6e38413293c224e70f627fb3 100644 (file)
@@ -47,7 +47,11 @@ error[E0277]: the trait bound `T: Copy` is not satisfied
 LL |     type C where Self: Copy = String;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `T`
    |
-   = note: required because of the requirements on the impl of `Copy` for `Fooy<T>`
+note: required because of the requirements on the impl of `Copy` for `Fooy<T>`
+  --> $DIR/impl_bounds.rs:11:10
+   |
+LL | #[derive(Copy, Clone)]
+   |          ^^^^
 note: the requirement `Fooy<T>: Copy` appears on the associated impl type `C` but not on the corresponding associated trait type
   --> $DIR/impl_bounds.rs:7:5
    |
@@ -56,6 +60,7 @@ LL | trait Foo {
 ...
 LL |     type C where Self: Clone;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^ this trait associated type doesn't have the requirement `Fooy<T>: Copy`
+   = note: this error originates in the derive macro `Copy` (in Nightly builds, run with -Z macro-backtrace for more info)
 help: consider restricting type parameter `T`
    |
 LL | impl<T: std::marker::Copy> Foo for Fooy<T> {
@@ -67,7 +72,11 @@ error[E0277]: the trait bound `T: Copy` is not satisfied
 LL |     fn d() where Self: Copy {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `T`
    |
-   = note: required because of the requirements on the impl of `Copy` for `Fooy<T>`
+note: required because of the requirements on the impl of `Copy` for `Fooy<T>`
+  --> $DIR/impl_bounds.rs:11:10
+   |
+LL | #[derive(Copy, Clone)]
+   |          ^^^^
 note: the requirement `Fooy<T>: Copy` appears on the impl method `d` but not on the corresponding trait method
   --> $DIR/impl_bounds.rs:8:8
    |
@@ -76,6 +85,7 @@ LL | trait Foo {
 ...
 LL |     fn d() where Self: Clone;
    |        ^ this trait method doesn't have the requirement `Fooy<T>: Copy`
+   = note: this error originates in the derive macro `Copy` (in Nightly builds, run with -Z macro-backtrace for more info)
 help: consider restricting type parameter `T`
    |
 LL | impl<T: std::marker::Copy> Foo for Fooy<T> {
index 8cc9f2816a166a30e05548ba800dd156a1c899b4..b4b89ab047363ce28c2cf43558a2c455b4484b8a 100644 (file)
@@ -1,8 +1,8 @@
 error[E0038]: the trait `X` cannot be made into an object
-  --> $DIR/issue-67510-pass.rs:7:19
+  --> $DIR/issue-67510-pass.rs:7:23
    |
 LL | fn _func1<'a>(_x: Box<dyn X<Y<'a>=&'a ()>>) {}
-   |                   ^^^^^^^^^^^^^^^^^^^^^^^^ `X` cannot be made into an object
+   |                       ^^^^^^^^^^^^^^^^^^^ `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>
diff --git a/src/test/ui/generic-associated-types/issue-78113-lifetime-mismatch-dyn-trait-box.rs b/src/test/ui/generic-associated-types/issue-78113-lifetime-mismatch-dyn-trait-box.rs
new file mode 100644 (file)
index 0000000..850d83b
--- /dev/null
@@ -0,0 +1,40 @@
+// Test for diagnostics when we have mismatched lifetime due to implict 'static lifetime in GATs
+
+// check-fail
+
+#![feature(generic_associated_types)]
+
+pub trait A {}
+impl A for &dyn A {}
+impl A for Box<dyn A> {}
+
+pub trait B {
+    type T<'a>: A;
+}
+
+impl B for () {
+    // `'a` doesn't match implicit `'static`: suggest `'_`
+    type T<'a> = Box<dyn A + 'a>; //~ incompatible lifetime on type
+}
+
+trait C {}
+impl C for Box<dyn A + 'static> {}
+pub trait D {
+    type T<'a>: C;
+}
+impl D for () {
+    // `'a` doesn't match explicit `'static`: we *should* suggest removing `'static`
+    type T<'a> = Box<dyn A + 'a>; //~ incompatible lifetime on type
+}
+
+trait E {}
+impl E for (Box<dyn A>, Box<dyn A>) {}
+pub trait F {
+    type T<'a>: E;
+}
+impl F for () {
+    // `'a` doesn't match explicit `'static`: suggest `'_`
+    type T<'a> = (Box<dyn A + 'a>, Box<dyn A + 'a>); //~ incompatible lifetime on type
+}
+
+fn main() {}
diff --git a/src/test/ui/generic-associated-types/issue-78113-lifetime-mismatch-dyn-trait-box.stderr b/src/test/ui/generic-associated-types/issue-78113-lifetime-mismatch-dyn-trait-box.stderr
new file mode 100644 (file)
index 0000000..fedc6a3
--- /dev/null
@@ -0,0 +1,87 @@
+error: incompatible lifetime on type
+  --> $DIR/issue-78113-lifetime-mismatch-dyn-trait-box.rs:17:5
+   |
+LL |     type T<'a> = Box<dyn A + 'a>;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: because this has an unmet lifetime requirement
+  --> $DIR/issue-78113-lifetime-mismatch-dyn-trait-box.rs:12:17
+   |
+LL |     type T<'a>: A;
+   |                 ^ introduces a `'static` lifetime requirement
+note: the lifetime `'a` as defined on the associated item at 17:12...
+  --> $DIR/issue-78113-lifetime-mismatch-dyn-trait-box.rs:17:12
+   |
+LL |     type T<'a> = Box<dyn A + 'a>;
+   |            ^^
+   = note: ...does not necessarily outlive the static lifetime introduced by the compatible `impl`
+note: this has an implicit `'static` lifetime requirement
+  --> $DIR/issue-78113-lifetime-mismatch-dyn-trait-box.rs:9:20
+   |
+LL | impl A for Box<dyn A> {}
+   |                    ^
+help: consider relaxing the implicit `'static` requirement
+   |
+LL | impl A for Box<dyn A + '_> {}
+   |                      ^^^^
+
+error: incompatible lifetime on type
+  --> $DIR/issue-78113-lifetime-mismatch-dyn-trait-box.rs:27:5
+   |
+LL |     type T<'a> = Box<dyn A + 'a>;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: because this has an unmet lifetime requirement
+  --> $DIR/issue-78113-lifetime-mismatch-dyn-trait-box.rs:23:17
+   |
+LL |     type T<'a>: C;
+   |                 ^ introduces a `'static` lifetime requirement
+note: the lifetime `'a` as defined on the associated item at 27:12...
+  --> $DIR/issue-78113-lifetime-mismatch-dyn-trait-box.rs:27:12
+   |
+LL |     type T<'a> = Box<dyn A + 'a>;
+   |            ^^
+note: ...does not necessarily outlive the static lifetime introduced by the compatible `impl`
+  --> $DIR/issue-78113-lifetime-mismatch-dyn-trait-box.rs:21:1
+   |
+LL | impl C for Box<dyn A + 'static> {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: incompatible lifetime on type
+  --> $DIR/issue-78113-lifetime-mismatch-dyn-trait-box.rs:37:5
+   |
+LL |     type T<'a> = (Box<dyn A + 'a>, Box<dyn A + 'a>);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: because this has an unmet lifetime requirement
+  --> $DIR/issue-78113-lifetime-mismatch-dyn-trait-box.rs:33:17
+   |
+LL |     type T<'a>: E;
+   |                 ^ introduces a `'static` lifetime requirement
+note: the lifetime `'a` as defined on the associated item at 37:12...
+  --> $DIR/issue-78113-lifetime-mismatch-dyn-trait-box.rs:37:12
+   |
+LL |     type T<'a> = (Box<dyn A + 'a>, Box<dyn A + 'a>);
+   |            ^^
+   = note: ...does not necessarily outlive the static lifetime introduced by the compatible `impl`
+note: this has an implicit `'static` lifetime requirement
+  --> $DIR/issue-78113-lifetime-mismatch-dyn-trait-box.rs:31:21
+   |
+LL | impl E for (Box<dyn A>, Box<dyn A>) {}
+   |                     ^
+note: this has an implicit `'static` lifetime requirement
+  --> $DIR/issue-78113-lifetime-mismatch-dyn-trait-box.rs:31:33
+   |
+LL | impl E for (Box<dyn A>, Box<dyn A>) {}
+   |                                 ^
+help: consider relaxing the implicit `'static` requirement
+   |
+LL | impl E for (Box<dyn A + '_>, Box<dyn A>) {}
+   |                       ^^^^
+help: consider relaxing the implicit `'static` requirement
+   |
+LL | impl E for (Box<dyn A>, Box<dyn A + '_>) {}
+   |                                   ^^^^
+
+error: aborting due to 3 previous errors
+
diff --git a/src/test/ui/generic-associated-types/issue-81487.rs b/src/test/ui/generic-associated-types/issue-81487.rs
new file mode 100644 (file)
index 0000000..7f399c4
--- /dev/null
@@ -0,0 +1,19 @@
+// build-pass
+
+#![feature(generic_associated_types)]
+
+trait Trait {
+    type Ref<'a>;
+}
+
+impl Trait for () {
+    type Ref<'a> = &'a i8;
+}
+
+struct RefRef<'a, T: Trait>(&'a <T as Trait>::Ref<'a>);
+
+fn wrap<'a, T: Trait>(reff: &'a <T as Trait>::Ref<'a>) -> RefRef<'a, T> {
+    RefRef(reff)
+}
+
+fn main() {}
index a121566bbd884be69a820ede9604e4f355d3bcd5..6429bb8159e1f9899debc6bce4e7d442e6148a3e 100644 (file)
@@ -1,8 +1,8 @@
 error[E0038]: the trait `StreamingIterator` cannot be made into an object
-  --> $DIR/trait-objects.rs:10:16
+  --> $DIR/trait-objects.rs:10:21
    |
 LL | fn min_size(x: &mut dyn for<'a> StreamingIterator<Item<'a> = &'a i32>) -> usize {
-   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `StreamingIterator` cannot be made into an object
+   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `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>
index 6500a2a55f6677d807922ec67f2cff89d53f6fe3..1c81c69620165df971959f6fc3ecb7d024f75f99 100644 (file)
@@ -3,6 +3,8 @@ error[E0726]: implicit elided lifetime not allowed here
    |
 LL | impl MyTrait for Foo {
    |                  ^^^- help: indicate the anonymous lifetime: `<'_>`
+   |
+   = note: assuming a `'static` lifetime...
 
 error: aborting due to previous error
 
index ad97cb0abd6239bc34ba3c0f04e0034a0ad0e8e8..735f01379f09fc4f50ceb45157e0543f25d9a483 100644 (file)
@@ -3,6 +3,8 @@ error[E0726]: implicit elided lifetime not allowed here
    |
 LL | impl MyTrait for u32 {
    |      ^^^^^^^- help: indicate the anonymous lifetime: `<'_>`
+   |
+   = note: assuming a `'static` lifetime...
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/impl-trait/binding-without-value.rs b/src/test/ui/impl-trait/binding-without-value.rs
deleted file mode 100644 (file)
index 6a97f28..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-#![allow(incomplete_features)]
-#![feature(impl_trait_in_bindings)]
-
-fn foo() {
-    let _ : impl Copy;
-    //~^ ERROR cannot resolve opaque type
-}
-
-fn main() {}
diff --git a/src/test/ui/impl-trait/binding-without-value.stderr b/src/test/ui/impl-trait/binding-without-value.stderr
deleted file mode 100644 (file)
index 0d2faea..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-error[E0720]: cannot resolve opaque type
-  --> $DIR/binding-without-value.rs:5:13
-   |
-LL |     let _ : impl Copy;
-   |         -   ^^^^^^^^^ cannot resolve opaque type
-   |         |
-   |         this binding might not have a concrete type
-   |
-help: set the binding to a value for a concrete type to be resolved
-   |
-LL |     let _ : impl Copy = /* value */;
-   |                       ^^^^^^^^^^^^^
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0720`.
diff --git a/src/test/ui/impl-trait/bindings-opaque.rs b/src/test/ui/impl-trait/bindings-opaque.rs
deleted file mode 100644 (file)
index d1f42be..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-#![feature(impl_trait_in_bindings)]
-//~^ WARN the feature `impl_trait_in_bindings` is incomplete
-
-const FOO: impl Copy = 42;
-
-static BAR: impl Copy = 42;
-
-fn main() {
-    let foo: impl Copy = 42;
-
-    let _ = FOO.count_ones();
-//~^ ERROR no method
-    let _ = BAR.count_ones();
-//~^ ERROR no method
-    let _ = foo.count_ones();
-//~^ ERROR no method
-}
diff --git a/src/test/ui/impl-trait/bindings-opaque.stderr b/src/test/ui/impl-trait/bindings-opaque.stderr
deleted file mode 100644 (file)
index 170bd46..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-warning: the feature `impl_trait_in_bindings` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/bindings-opaque.rs:1:12
-   |
-LL | #![feature(impl_trait_in_bindings)]
-   |            ^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(incomplete_features)]` on by default
-   = note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
-
-error[E0599]: no method named `count_ones` found for opaque type `impl Copy` in the current scope
-  --> $DIR/bindings-opaque.rs:11:17
-   |
-LL |     let _ = FOO.count_ones();
-   |                 ^^^^^^^^^^ method not found in `impl Copy`
-
-error[E0599]: no method named `count_ones` found for opaque type `impl Copy` in the current scope
-  --> $DIR/bindings-opaque.rs:13:17
-   |
-LL |     let _ = BAR.count_ones();
-   |                 ^^^^^^^^^^ method not found in `impl Copy`
-
-error[E0599]: no method named `count_ones` found for opaque type `impl Copy` in the current scope
-  --> $DIR/bindings-opaque.rs:15:17
-   |
-LL |     let _ = foo.count_ones();
-   |                 ^^^^^^^^^^ method not found in `impl Copy`
-
-error: aborting due to 3 previous errors; 1 warning emitted
-
-For more information about this error, try `rustc --explain E0599`.
diff --git a/src/test/ui/impl-trait/bindings.rs b/src/test/ui/impl-trait/bindings.rs
deleted file mode 100644 (file)
index fd79ba6..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-#![feature(impl_trait_in_bindings)]
-//~^ WARN the feature `impl_trait_in_bindings` is incomplete
-
-fn a<T: Clone>(x: T) {
-    const foo: impl Clone = x;
-    //~^ ERROR attempt to use a non-constant value in a constant
-}
-
-fn b<T: Clone>(x: T) {
-    let _ = move || {
-        const foo: impl Clone = x;
-        //~^ ERROR attempt to use a non-constant value in a constant
-    };
-}
-
-trait Foo<T: Clone> {
-    fn a(x: T) {
-        const foo: impl Clone = x;
-        //~^ ERROR attempt to use a non-constant value in a constant
-    }
-}
-
-impl<T: Clone> Foo<T> for i32 {
-    fn a(x: T) {
-        const foo: impl Clone = x;
-        //~^ ERROR attempt to use a non-constant value in a constant
-    }
-}
-
-fn main() { }
diff --git a/src/test/ui/impl-trait/bindings.stderr b/src/test/ui/impl-trait/bindings.stderr
deleted file mode 100644 (file)
index 4da49f4..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-error[E0435]: attempt to use a non-constant value in a constant
-  --> $DIR/bindings.rs:5:29
-   |
-LL |     const foo: impl Clone = x;
-   |     ---------               ^ non-constant value
-   |     |
-   |     help: consider using `let` instead of `const`: `let foo`
-
-error[E0435]: attempt to use a non-constant value in a constant
-  --> $DIR/bindings.rs:11:33
-   |
-LL |         const foo: impl Clone = x;
-   |         ---------               ^ non-constant value
-   |         |
-   |         help: consider using `let` instead of `const`: `let foo`
-
-error[E0435]: attempt to use a non-constant value in a constant
-  --> $DIR/bindings.rs:18:33
-   |
-LL |         const foo: impl Clone = x;
-   |         ---------               ^ non-constant value
-   |         |
-   |         help: consider using `let` instead of `const`: `let foo`
-
-error[E0435]: attempt to use a non-constant value in a constant
-  --> $DIR/bindings.rs:25:33
-   |
-LL |         const foo: impl Clone = x;
-   |         ---------               ^ non-constant value
-   |         |
-   |         help: consider using `let` instead of `const`: `let foo`
-
-warning: the feature `impl_trait_in_bindings` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/bindings.rs:1:12
-   |
-LL | #![feature(impl_trait_in_bindings)]
-   |            ^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(incomplete_features)]` on by default
-   = note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
-
-error: aborting due to 4 previous errors; 1 warning emitted
-
-For more information about this error, try `rustc --explain E0435`.
index d3056fb8851257aced8142dcb3224fc6be1ab0d9..8ec06e534d14336bd569ab85a615539a542475b3 100644 (file)
@@ -1,15 +1,14 @@
 // edition:2018
 
-#![feature(impl_trait_in_bindings)]
-//~^ WARNING the feature `impl_trait_in_bindings` is incomplete
-
 // See issue 60414
 
 // Reduction to `impl Trait`
 
 struct Foo<T>(T);
 
-trait FooLike { type Output; }
+trait FooLike {
+    type Output;
+}
 
 impl<T> FooLike for Foo<T> {
     type Output = T;
@@ -23,7 +22,7 @@ trait Trait {
     }
 
     /// `T::Assoc` can't be normalized any further here.
-    fn foo_fail<T: Trait>() -> impl FooLike<Output=T::Assoc> {
+    fn foo_fail<T: Trait>() -> impl FooLike<Output = T::Assoc> {
         //~^ ERROR: type mismatch
         Foo(())
     }
@@ -39,9 +38,9 @@ trait Trait<'a> {
     }
 
     /// Missing bound constraining `Assoc`, `T::Assoc` can't be normalized further.
-    fn foo2_fail<'a, T: Trait<'a>>() -> impl FooLike<Output=T::Assoc> {
-    //~^ ERROR: type mismatch
-    //~^^ ERROR `impl Trait` return type cannot contain a projection or `Self` that references lifetimes from a parent scope
+    fn foo2_fail<'a, T: Trait<'a>>() -> impl FooLike<Output = T::Assoc> {
+        //~^ ERROR: type mismatch
+        //~^^ ERROR `impl Trait` return type cannot contain a projection or `Self` that references lifetimes from a parent scope
         Foo(())
     }
 }
index ba3a2e7f8d4c9445aff1b79fa3e2423dd1a3fad7..611543a19260b05863eb6a5fb51a12422a45d3a4 100644 (file)
@@ -1,45 +1,36 @@
-warning: the feature `impl_trait_in_bindings` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/bound-normalization-fail.rs:3:12
-   |
-LL | #![feature(impl_trait_in_bindings)]
-   |            ^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(incomplete_features)]` on by default
-   = note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
-
 error[E0271]: type mismatch resolving `<Foo<()> as FooLike>::Output == <T as impl_trait::Trait>::Assoc`
-  --> $DIR/bound-normalization-fail.rs:26:32
+  --> $DIR/bound-normalization-fail.rs:25:32
    |
-LL |     fn foo_fail<T: Trait>() -> impl FooLike<Output=T::Assoc> {
-   |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected associated type, found `()`
+LL |     fn foo_fail<T: Trait>() -> impl FooLike<Output = T::Assoc> {
+   |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected associated type, found `()`
    |
    = note: expected associated type `<T as impl_trait::Trait>::Assoc`
                          found type `()`
 help: consider constraining the associated type `<T as impl_trait::Trait>::Assoc` to `()`
    |
-LL |     fn foo_fail<T: Trait<Assoc = ()>>() -> impl FooLike<Output=T::Assoc> {
+LL |     fn foo_fail<T: Trait<Assoc = ()>>() -> impl FooLike<Output = T::Assoc> {
    |                         ^^^^^^^^^^^^
 
 error[E0760]: `impl Trait` return type cannot contain a projection or `Self` that references lifetimes from a parent scope
-  --> $DIR/bound-normalization-fail.rs:42:41
+  --> $DIR/bound-normalization-fail.rs:41:41
    |
-LL |     fn foo2_fail<'a, T: Trait<'a>>() -> impl FooLike<Output=T::Assoc> {
-   |                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     fn foo2_fail<'a, T: Trait<'a>>() -> impl FooLike<Output = T::Assoc> {
+   |                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0271]: type mismatch resolving `<Foo<()> as FooLike>::Output == <T as lifetimes::Trait<'static>>::Assoc`
-  --> $DIR/bound-normalization-fail.rs:42:41
+  --> $DIR/bound-normalization-fail.rs:41:41
    |
-LL |     fn foo2_fail<'a, T: Trait<'a>>() -> impl FooLike<Output=T::Assoc> {
-   |                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected associated type, found `()`
+LL |     fn foo2_fail<'a, T: Trait<'a>>() -> impl FooLike<Output = T::Assoc> {
+   |                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected associated type, found `()`
    |
    = note: expected associated type `<T as lifetimes::Trait<'static>>::Assoc`
                          found type `()`
 help: consider constraining the associated type `<T as lifetimes::Trait<'static>>::Assoc` to `()`
    |
-LL |     fn foo2_fail<'a, T: Trait<'a, Assoc = ()>>() -> impl FooLike<Output=T::Assoc> {
+LL |     fn foo2_fail<'a, T: Trait<'a, Assoc = ()>>() -> impl FooLike<Output = T::Assoc> {
    |                                 ^^^^^^^^^^^^
 
-error: aborting due to 3 previous errors; 1 warning emitted
+error: aborting due to 3 previous errors
 
 Some errors have detailed explanations: E0271, E0760.
 For more information about an error, try `rustc --explain E0271`.
diff --git a/src/test/ui/impl-trait/bound-normalization-pass.default.stderr b/src/test/ui/impl-trait/bound-normalization-pass.default.stderr
deleted file mode 100644 (file)
index ef3cb74..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-warning: the feature `impl_trait_in_bindings` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/bound-normalization-pass.rs:8:12
-   |
-LL | #![feature(impl_trait_in_bindings)]
-   |            ^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(incomplete_features)]` on by default
-   = note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
-
-warning: 1 warning emitted
-
index 6a01753b4c29caafad20bfc95700a511a56e4359..4218bc5206596b84d0e9b4f5c988fe5e8079dab0 100644 (file)
@@ -5,8 +5,6 @@
 //-^ To make this the regression test for #75962.
 
 #![feature(min_type_alias_impl_trait)]
-#![feature(impl_trait_in_bindings)]
-//~^ WARNING the feature `impl_trait_in_bindings` is incomplete
 
 // See issue 60414
 
@@ -14,7 +12,9 @@
 
 struct Foo<T>(T);
 
-trait FooLike { type Output; }
+trait FooLike {
+    type Output;
+}
 
 impl<T> FooLike for Foo<T> {
     type Output = T;
@@ -28,7 +28,7 @@ trait Trait {
     }
 
     /// `T::Assoc` should be normalized to `()` here.
-    fn foo_pass<T: Trait<Assoc=()>>() -> impl FooLike<Output=T::Assoc> {
+    fn foo_pass<T: Trait<Assoc = ()>>() -> impl FooLike<Output = T::Assoc> {
         Foo(())
     }
 }
@@ -45,40 +45,20 @@ trait Trait<'a> {
     /// Like above.
     ///
     /// FIXME(#51525) -- the shorter notation `T::Assoc` winds up referencing `'static` here
-    fn foo2_pass<'a, T: Trait<'a, Assoc=()> + 'a>(
-    ) -> impl FooLike<Output=<T as Trait<'a>>::Assoc> + 'a {
+    fn foo2_pass<'a, T: Trait<'a, Assoc = ()> + 'a>()
+    -> impl FooLike<Output = <T as Trait<'a>>::Assoc> + 'a {
         Foo(())
     }
 
     /// Normalization to type containing bound region.
     ///
     /// FIXME(#51525) -- the shorter notation `T::Assoc` winds up referencing `'static` here
-    fn foo2_pass2<'a, T: Trait<'a, Assoc=&'a ()> + 'a>(
-    ) -> impl FooLike<Output=<T as Trait<'a>>::Assoc> + 'a {
+    fn foo2_pass2<'a, T: Trait<'a, Assoc = &'a ()> + 'a>()
+    -> impl FooLike<Output = <T as Trait<'a>>::Assoc> + 'a {
         Foo(&())
     }
 }
 
-// Reduction using `impl Trait` in bindings
-
-mod impl_trait_in_bindings {
-    struct Foo;
-
-    trait FooLike { type Output; }
-
-    impl FooLike for Foo {
-        type Output = u32;
-    }
-
-    trait Trait {
-        type Assoc;
-    }
-
-    fn foo<T: Trait<Assoc=u32>>() {
-        let _: impl FooLike<Output=T::Assoc> = Foo;
-    }
-}
-
 // The same applied to `type Foo = impl Bar`s
 
 mod opaque_types {
diff --git a/src/test/ui/impl-trait/bound-normalization-pass.sa.stderr b/src/test/ui/impl-trait/bound-normalization-pass.sa.stderr
deleted file mode 100644 (file)
index ef3cb74..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-warning: the feature `impl_trait_in_bindings` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/bound-normalization-pass.rs:8:12
-   |
-LL | #![feature(impl_trait_in_bindings)]
-   |            ^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(incomplete_features)]` on by default
-   = note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
-
-warning: 1 warning emitted
-
diff --git a/src/test/ui/impl-trait/impl-trait-in-bindings-issue-73003.rs b/src/test/ui/impl-trait/impl-trait-in-bindings-issue-73003.rs
deleted file mode 100644 (file)
index fd8fe5f..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-// check-pass
-
-#![feature(impl_trait_in_bindings)]
-//~^ WARN the feature `impl_trait_in_bindings` is incomplete
-
-const _: impl Fn() = ||();
-
-fn main() {}
diff --git a/src/test/ui/impl-trait/impl-trait-in-bindings-issue-73003.stderr b/src/test/ui/impl-trait/impl-trait-in-bindings-issue-73003.stderr
deleted file mode 100644 (file)
index 715671c..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-warning: the feature `impl_trait_in_bindings` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/impl-trait-in-bindings-issue-73003.rs:3:12
-   |
-LL | #![feature(impl_trait_in_bindings)]
-   |            ^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(incomplete_features)]` on by default
-   = note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
-
-warning: 1 warning emitted
-
diff --git a/src/test/ui/impl-trait/impl-trait-in-bindings.rs b/src/test/ui/impl-trait/impl-trait-in-bindings.rs
deleted file mode 100644 (file)
index c7fae45..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-// run-pass
-
-#![feature(impl_trait_in_bindings)]
-//~^ WARN the feature `impl_trait_in_bindings` is incomplete
-
-use std::fmt::Debug;
-
-const FOO: impl Debug + Clone + PartialEq<i32> = 42;
-
-static BAR: impl Debug + Clone + PartialEq<i32> = 42;
-
-fn a<T: Clone>(x: T) {
-    let y: impl Clone = x;
-    let _ = y.clone();
-}
-
-fn b<T: Clone>(x: T) {
-    let f = move || {
-        let y: impl Clone = x;
-        let _ = y.clone();
-    };
-    f();
-}
-
-trait Foo<T: Clone> {
-    fn a(x: T) {
-        let y: impl Clone = x;
-        let _ = y.clone();
-    }
-}
-
-impl<T: Clone> Foo<T> for i32 {
-    fn a(x: T) {
-        let y: impl Clone = x;
-        let _ = y.clone();
-    }
-}
-
-fn main() {
-    let foo: impl Debug + Clone + PartialEq<i32> = 42;
-
-    assert_eq!(FOO.clone(), 42);
-    assert_eq!(BAR.clone(), 42);
-    assert_eq!(foo.clone(), 42);
-
-    a(42);
-    b(42);
-    i32::a(42);
-}
diff --git a/src/test/ui/impl-trait/impl-trait-in-bindings.stderr b/src/test/ui/impl-trait/impl-trait-in-bindings.stderr
deleted file mode 100644 (file)
index bf739d4..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-warning: the feature `impl_trait_in_bindings` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/impl-trait-in-bindings.rs:3:12
-   |
-LL | #![feature(impl_trait_in_bindings)]
-   |            ^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(incomplete_features)]` on by default
-   = note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
-
-warning: 1 warning emitted
-
diff --git a/src/test/ui/impl-trait/issue-57200.rs b/src/test/ui/impl-trait/issue-57200.rs
deleted file mode 100644 (file)
index e0c71d1..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-// Regression test for #57200
-// FIXME: The error is temporary hack, we'll revisit here at some point.
-
-#![feature(impl_trait_in_bindings)]
-#![allow(incomplete_features)]
-
-fn bug<'a, 'b, T>()
-where
-    'a: 'b,
-{
-    let f: impl Fn(&'a T) -> &'b T = |x| x;
-    //~^ ERROR: lifetimes in impl Trait types in bindings are not currently supported
-}
-
-fn main() {}
diff --git a/src/test/ui/impl-trait/issue-57200.stderr b/src/test/ui/impl-trait/issue-57200.stderr
deleted file mode 100644 (file)
index b44f332..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-error: lifetimes in impl Trait types in bindings are not currently supported
-  --> $DIR/issue-57200.rs:11:12
-   |
-LL |     let f: impl Fn(&'a T) -> &'b T = |x| x;
-   |            ^^^^^^^^^^^^^^^^^^^^^^^
-
-error: aborting due to previous error
-
diff --git a/src/test/ui/impl-trait/issue-57201.rs b/src/test/ui/impl-trait/issue-57201.rs
deleted file mode 100644 (file)
index c1a98d8..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-// Regression test for #57201
-// FIXME: The error is temporary hack, we'll revisit here at some point.
-
-#![feature(impl_trait_in_bindings)]
-#![allow(incomplete_features)]
-
-fn bug<'a, 'b, T>()
-where
-    'a: 'b,
-{
-    let f: &impl Fn(&'a T) -> &'b T = &|x| x;
-    //~^ ERROR: lifetimes in impl Trait types in bindings are not currently supported
-}
-
-fn main() {}
diff --git a/src/test/ui/impl-trait/issue-57201.stderr b/src/test/ui/impl-trait/issue-57201.stderr
deleted file mode 100644 (file)
index 462b17b..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-error: lifetimes in impl Trait types in bindings are not currently supported
-  --> $DIR/issue-57201.rs:11:13
-   |
-LL |     let f: &impl Fn(&'a T) -> &'b T = &|x| x;
-   |             ^^^^^^^^^^^^^^^^^^^^^^^
-
-error: aborting due to previous error
-
diff --git a/src/test/ui/impl-trait/issue-60473.rs b/src/test/ui/impl-trait/issue-60473.rs
deleted file mode 100644 (file)
index 2ef86f0..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-// Regression test for #60473
-
-#![feature(impl_trait_in_bindings)]
-#![allow(incomplete_features)]
-
-struct A<'a>(&'a ());
-
-trait Trait<T> {}
-
-impl<T> Trait<T> for () {}
-
-fn main() {
-    let x: impl Trait<A> = ();
-    //~^ ERROR: missing lifetime specifier
-}
diff --git a/src/test/ui/impl-trait/issue-60473.stderr b/src/test/ui/impl-trait/issue-60473.stderr
deleted file mode 100644 (file)
index 367b5db..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-error[E0106]: missing lifetime specifier
-  --> $DIR/issue-60473.rs:13:23
-   |
-LL |     let x: impl Trait<A> = ();
-   |                       ^ expected named lifetime parameter
-   |
-help: consider introducing a named lifetime parameter
-   |
-LL | fn main<'a>() {
-LL |     let x: impl Trait<A<'a>> = ();
-   |
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0106`.
diff --git a/src/test/ui/impl-trait/issue-67166.rs b/src/test/ui/impl-trait/issue-67166.rs
deleted file mode 100644 (file)
index efa6755..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-// Regression test for #67166
-
-#![feature(impl_trait_in_bindings)]
-#![allow(incomplete_features)]
-
-pub fn run() {
-    let _foo: Box<impl Copy + '_> = Box::new(());
-    //~^ ERROR: missing lifetime specifier
-}
-
-fn main() {}
diff --git a/src/test/ui/impl-trait/issue-67166.stderr b/src/test/ui/impl-trait/issue-67166.stderr
deleted file mode 100644 (file)
index 14c7868..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-error[E0106]: missing lifetime specifier
-  --> $DIR/issue-67166.rs:7:31
-   |
-LL |     let _foo: Box<impl Copy + '_> = Box::new(());
-   |                               ^^ expected named lifetime parameter
-   |
-help: consider introducing a named lifetime parameter
-   |
-LL | pub fn run<'a>() {
-LL |     let _foo: Box<impl Copy + 'a> = Box::new(());
-   |
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0106`.
diff --git a/src/test/ui/impl-trait/issue-69840.rs b/src/test/ui/impl-trait/issue-69840.rs
deleted file mode 100644 (file)
index b270f88..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-// check-pass
-
-#![feature(impl_trait_in_bindings)]
-#![allow(incomplete_features)]
-
-struct A<'a>(&'a ());
-
-trait Trait<T> {}
-
-impl<T> Trait<T> for () {}
-
-pub fn foo<'a>() {
-    let _x: impl Trait<A<'a>> = ();
-}
-
-fn main() {}
index 8e42b9d46db390b9d61f6e6ee7e6e764f7f33adb..1f4e3f78afa45e23d368ccd218d967cb9aa86b71 100644 (file)
@@ -1,5 +1,5 @@
 error[E0271]: type mismatch resolving `<Bar as Iterator>::Item == Box<(dyn for<'r> Fn(&'r (dyn ToString + 'r)) -> Option<String> + 'static)>`
-  --> $DIR/issue-70877.rs:11:12
+  --> $DIR/issue-70877.rs:10:12
    |
 LL | type FooRet = impl std::fmt::Debug;
    |               -------------------- the found opaque type
index 8e42b9d46db390b9d61f6e6ee7e6e764f7f33adb..1f4e3f78afa45e23d368ccd218d967cb9aa86b71 100644 (file)
@@ -1,5 +1,5 @@
 error[E0271]: type mismatch resolving `<Bar as Iterator>::Item == Box<(dyn for<'r> Fn(&'r (dyn ToString + 'r)) -> Option<String> + 'static)>`
-  --> $DIR/issue-70877.rs:11:12
+  --> $DIR/issue-70877.rs:10:12
    |
 LL | type FooRet = impl std::fmt::Debug;
    |               -------------------- the found opaque type
index 7ca0f90e2dced687a3fbda9124f686e0e365059d..29aa705ef9d4df21dba80e04e00137f90d19f638 100644 (file)
@@ -1,7 +1,6 @@
 // revisions: min_tait full_tait
 #![feature(min_type_alias_impl_trait)]
 #![cfg_attr(full_tait, feature(type_alias_impl_trait))]
-#![feature(impl_trait_in_bindings)]
 #![allow(incomplete_features)]
 
 type FooArg<'a> = &'a dyn ToString;
diff --git a/src/test/ui/impl-trait/issues/issue-78721.rs b/src/test/ui/impl-trait/issues/issue-78721.rs
deleted file mode 100644 (file)
index f7dbef9..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-// edition:2018
-
-#![feature(impl_trait_in_bindings)]
-//~^ WARN the feature `impl_trait_in_bindings` is incomplete
-
-struct Bug {
-    V1: [(); {
-        let f: impl core::future::Future<Output = u8> = async { 1 };
-        //~^ ERROR `async` blocks are not allowed in constants
-        //~| ERROR destructors cannot be evaluated at compile-time
-        1
-    }],
-}
-
-fn main() {}
diff --git a/src/test/ui/impl-trait/issues/issue-78721.stderr b/src/test/ui/impl-trait/issues/issue-78721.stderr
deleted file mode 100644 (file)
index d5712dd..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-warning: the feature `impl_trait_in_bindings` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/issue-78721.rs:3:12
-   |
-LL | #![feature(impl_trait_in_bindings)]
-   |            ^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(incomplete_features)]` on by default
-   = note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
-
-error[E0658]: `async` blocks are not allowed in constants
-  --> $DIR/issue-78721.rs:8:57
-   |
-LL |         let f: impl core::future::Future<Output = u8> = async { 1 };
-   |                                                         ^^^^^^^^^^^
-   |
-   = note: see issue #85368 <https://github.com/rust-lang/rust/issues/85368> for more information
-   = help: add `#![feature(const_async_blocks)]` to the crate attributes to enable
-
-error[E0493]: destructors cannot be evaluated at compile-time
-  --> $DIR/issue-78721.rs:8:13
-   |
-LL |         let f: impl core::future::Future<Output = u8> = async { 1 };
-   |             ^ constants cannot evaluate destructors
-...
-LL |     }],
-   |     - value is dropped here
-
-error: aborting due to 2 previous errors; 1 warning emitted
-
-Some errors have detailed explanations: E0493, E0658.
-For more information about an error, try `rustc --explain E0493`.
index 7a4be1d5f6df271a84a543817b333b8a03d13713..728644f7579917960b8b85791bd759baafcb9730 100644 (file)
@@ -7,33 +7,26 @@ LL | #![cfg_attr(full_tait, feature(type_alias_impl_trait))]
    = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #63063 <https://github.com/rust-lang/rust/issues/63063> for more information
 
-warning: the feature `impl_trait_in_bindings` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/issue-78722.rs:7:12
-   |
-LL | #![feature(impl_trait_in_bindings)]
-   |            ^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
-
-error[E0658]: `async` blocks are not allowed in constants
-  --> $DIR/issue-78722.rs:17:20
+error[E0308]: mismatched types
+  --> $DIR/issue-78722.rs:15:20
    |
+LL | type F = impl core::future::Future<Output = u8>;
+   |          -------------------------------------- the expected opaque type
+...
 LL |         let f: F = async { 1 };
-   |                    ^^^^^^^^^^^
+   |                -   ^^^^^^^^^^^ expected opaque type, found a different opaque type
+   |                |
+   |                expected due to this
+   | 
+  ::: $SRC_DIR/core/src/future/mod.rs:LL:COL
    |
-   = note: see issue #85368 <https://github.com/rust-lang/rust/issues/85368> for more information
-   = help: add `#![feature(const_async_blocks)]` to the crate attributes to enable
-
-error[E0493]: destructors cannot be evaluated at compile-time
-  --> $DIR/issue-78722.rs:17:13
+LL | pub const fn from_generator<T>(gen: T) -> impl Future<Output = T::Return>
+   |                                           ------------------------------- the found opaque type
    |
-LL |         let f: F = async { 1 };
-   |             ^ constants cannot evaluate destructors
-...
-LL |     }],
-   |     - value is dropped here
+   = note: expected opaque type `impl Future` (opaque type at <$DIR/issue-78722.rs:8:10>)
+              found opaque type `impl Future` (opaque type at <$SRC_DIR/core/src/future/mod.rs:LL:COL>)
+   = note: distinct uses of `impl Trait` result in different opaque types
 
-error: aborting due to 2 previous errors; 2 warnings emitted
+error: aborting due to previous error; 1 warning emitted
 
-Some errors have detailed explanations: E0493, E0658.
-For more information about an error, try `rustc --explain E0493`.
+For more information about this error, try `rustc --explain E0308`.
index 131033063d209579973c5a80f0a3d3c607de69bb..221b23ae3d2adf08de38f81dad208f370fc77277 100644 (file)
@@ -1,31 +1,23 @@
-warning: the feature `impl_trait_in_bindings` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/issue-78722.rs:7:12
-   |
-LL | #![feature(impl_trait_in_bindings)]
-   |            ^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(incomplete_features)]` on by default
-   = note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
-
-error[E0658]: `async` blocks are not allowed in constants
-  --> $DIR/issue-78722.rs:17:20
+error[E0308]: mismatched types
+  --> $DIR/issue-78722.rs:15:20
    |
+LL | type F = impl core::future::Future<Output = u8>;
+   |          -------------------------------------- the expected opaque type
+...
 LL |         let f: F = async { 1 };
-   |                    ^^^^^^^^^^^
+   |                -   ^^^^^^^^^^^ expected opaque type, found a different opaque type
+   |                |
+   |                expected due to this
+   | 
+  ::: $SRC_DIR/core/src/future/mod.rs:LL:COL
    |
-   = note: see issue #85368 <https://github.com/rust-lang/rust/issues/85368> for more information
-   = help: add `#![feature(const_async_blocks)]` to the crate attributes to enable
-
-error[E0493]: destructors cannot be evaluated at compile-time
-  --> $DIR/issue-78722.rs:17:13
+LL | pub const fn from_generator<T>(gen: T) -> impl Future<Output = T::Return>
+   |                                           ------------------------------- the found opaque type
    |
-LL |         let f: F = async { 1 };
-   |             ^ constants cannot evaluate destructors
-...
-LL |     }],
-   |     - value is dropped here
+   = note: expected opaque type `impl Future` (opaque type at <$DIR/issue-78722.rs:8:10>)
+              found opaque type `impl Future` (opaque type at <$SRC_DIR/core/src/future/mod.rs:LL:COL>)
+   = note: distinct uses of `impl Trait` result in different opaque types
 
-error: aborting due to 2 previous errors; 1 warning emitted
+error: aborting due to previous error
 
-Some errors have detailed explanations: E0493, E0658.
-For more information about an error, try `rustc --explain E0493`.
+For more information about this error, try `rustc --explain E0308`.
index 0999ec63e032c5cd4dec5a5d08033e579152b6fd..480b55eed21e2046c1c9e0b14b4f43cac489b38c 100644 (file)
@@ -4,8 +4,6 @@
 #![feature(min_type_alias_impl_trait)]
 #![cfg_attr(full_tait, feature(type_alias_impl_trait))]
 //[full_tait]~^ WARN incomplete
-#![feature(impl_trait_in_bindings)]
-//~^ WARN the feature `impl_trait_in_bindings` is incomplete
 
 type F = impl core::future::Future<Output = u8>;
 
@@ -15,8 +13,7 @@ fn concrete_use() -> F {
             async {}
         }
         let f: F = async { 1 };
-        //~^ ERROR `async` blocks are not allowed in constants
-        //~| ERROR destructors cannot be evaluated at compile-time
+        //~^ ERROR mismatched types [E0308]
         1
     }],
 }
index d9d2e3929b10c2cd3778b12f1527a6dbe814e09e..773cd0b81cc53ff6a2960ebee538d402a094ce3b 100644 (file)
@@ -1,8 +1,8 @@
 struct Foo<T = impl Copy>(T);
-//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+//~^ ERROR `impl Trait` not allowed outside of function and method return types
 
 type Result<T, E = impl std::error::Error> = std::result::Result<T, E>;
-//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+//~^ ERROR `impl Trait` not allowed outside of function and method return types
 
 // should not cause ICE
 fn x() -> Foo {
index eef6844adfccba365e4fb96ac8444d4819174068..d44dcf1f7fa2377c70220369bcab8dc95cb071de 100644 (file)
@@ -1,10 +1,10 @@
-error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+error[E0562]: `impl Trait` not allowed outside of function and method return types
   --> $DIR/issue-83929-impl-trait-in-generic-default.rs:1:16
    |
 LL | struct Foo<T = impl Copy>(T);
    |                ^^^^^^^^^
 
-error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+error[E0562]: `impl Trait` not allowed outside of function and method return types
   --> $DIR/issue-83929-impl-trait-in-generic-default.rs:4:20
    |
 LL | type Result<T, E = impl std::error::Error> = std::result::Result<T, E>;
index 4372de245078fc930be3cb4a27dd1f30e337be7d..e9d620877345423f65e0683bad69c34df47ab0ce 100644 (file)
@@ -9,7 +9,7 @@ LL | fn elided(x: &i32) -> impl Copy { x }
 help: to allow this `impl Trait` to capture borrowed data with lifetime `'1`, add `'_` as a bound
    |
 LL | fn elided(x: &i32) -> impl Copy + '_ { x }
-   |                       ^^^^^^^^^^^^^^
+   |                                 ^^^^
 
 error: lifetime may not live long enough
   --> $DIR/must_outlive_least_region_or_bound.rs:5:32
@@ -23,7 +23,7 @@ LL | fn explicit<'a>(x: &'a i32) -> impl Copy { x }
 help: to allow this `impl Trait` to capture borrowed data with lifetime `'a`, add `'a` as a bound
    |
 LL | fn explicit<'a>(x: &'a i32) -> impl Copy + 'a { x }
-   |                                ^^^^^^^^^^^^^^
+   |                                          ^^^^
 
 error: lifetime may not live long enough
   --> $DIR/must_outlive_least_region_or_bound.rs:7:46
index 3749c268a68b345e935cd57fd2d551d9a693d0a8..59c7e4d5f4e92b8aa0a8867f5e04120567f9a026 100644 (file)
@@ -34,13 +34,13 @@ LL |     fn bad(x: impl Into<u32>) -> impl Into<impl Debug> { x }
    |                                  |         nested `impl Trait` here
    |                                  outer `impl Trait`
 
-error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+error[E0562]: `impl Trait` not allowed outside of function and method return types
   --> $DIR/nested_impl_trait.rs:8:32
    |
 LL | fn bad_in_fn_syntax(x: fn() -> impl Into<impl Debug>) {}
    |                                ^^^^^^^^^^^^^^^^^^^^^
 
-error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+error[E0562]: `impl Trait` not allowed outside of function and method return types
   --> $DIR/nested_impl_trait.rs:25:42
    |
 LL | fn allowed_in_ret_type() -> impl Fn() -> impl Into<u32> {
index 65178cc9d24c262f3b186f99310df4a36a8c5330..6c5264671a9120c3f397bc612d465736f98a4d24 100644 (file)
@@ -9,7 +9,7 @@ LL |     fn iter_values_anon(&self) -> impl Iterator<Item=u32> {
 help: to allow this `impl Trait` to capture borrowed data with lifetime `'1`, add `'_` as a bound
    |
 LL |     fn iter_values_anon(&self) -> impl Iterator<Item=u32> + '_ {
-   |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                                                           ^^^^
 
 error: lifetime may not live long enough
   --> $DIR/static-return-lifetime-infered.rs:9:37
@@ -23,7 +23,7 @@ LL |     fn iter_values<'a>(&'a self) -> impl Iterator<Item=u32> {
 help: to allow this `impl Trait` to capture borrowed data with lifetime `'a`, add `'a` as a bound
    |
 LL |     fn iter_values<'a>(&'a self) -> impl Iterator<Item=u32> + 'a {
-   |                                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                                                             ^^^^
 
 error: aborting due to 2 previous errors
 
index c3e21c81f03bea8a33e7253a6ac8252a42b156d7..4605e76ac96d28a44cb50f3563daee0b2be0d873 100644 (file)
@@ -13,61 +13,61 @@ fn in_adt_in_parameters(_: Vec<impl Debug>) { panic!() }
 
 // Disallowed
 fn in_fn_parameter_in_parameters(_: fn(impl Debug)) { panic!() }
-//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+//~^ ERROR `impl Trait` not allowed outside of function and method return types
 
 // Disallowed
 fn in_fn_return_in_parameters(_: fn() -> impl Debug) { panic!() }
-//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+//~^ ERROR `impl Trait` not allowed outside of function and method return types
 
 // Disallowed
 fn in_fn_parameter_in_return() -> fn(impl Debug) { panic!() }
-//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+//~^ ERROR `impl Trait` not allowed outside of function and method return types
 
 // Disallowed
 fn in_fn_return_in_return() -> fn() -> impl Debug { panic!() }
-//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+//~^ ERROR `impl Trait` not allowed outside of function and method return types
 
 // Disallowed
 fn in_dyn_Fn_parameter_in_parameters(_: &dyn Fn(impl Debug)) { panic!() }
-//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+//~^ ERROR `impl Trait` not allowed outside of function and method return types
 
 // Disallowed
 fn in_dyn_Fn_return_in_parameters(_: &dyn Fn() -> impl Debug) { panic!() }
-//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+//~^ ERROR `impl Trait` not allowed outside of function and method return types
 
 // Disallowed
 fn in_dyn_Fn_parameter_in_return() -> &'static dyn Fn(impl Debug) { panic!() }
-//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+//~^ ERROR `impl Trait` not allowed outside of function and method return types
 
 // Disallowed
 fn in_dyn_Fn_return_in_return() -> &'static dyn Fn() -> impl Debug { panic!() }
-//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+//~^ ERROR `impl Trait` not allowed outside of function and method return types
 
 // Disallowed
 fn in_impl_Fn_parameter_in_parameters(_: &impl Fn(impl Debug)) { panic!() }
-//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+//~^ ERROR `impl Trait` not allowed outside of function and method return types
 //~^^ ERROR nested `impl Trait` is not allowed
 
 // Disallowed
 fn in_impl_Fn_return_in_parameters(_: &impl Fn() -> impl Debug) { panic!() }
-//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+//~^ ERROR `impl Trait` not allowed outside of function and method return types
 
 // Disallowed
 fn in_impl_Fn_parameter_in_return() -> &'static impl Fn(impl Debug) { panic!() }
-//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+//~^ ERROR `impl Trait` not allowed outside of function and method return types
 //~| ERROR nested `impl Trait` is not allowed
 
 // Disallowed
 fn in_impl_Fn_return_in_return() -> &'static impl Fn() -> impl Debug { panic!() }
-//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+//~^ ERROR `impl Trait` not allowed outside of function and method return types
 
 // Disallowed
 fn in_Fn_parameter_in_generics<F: Fn(impl Debug)> (_: F) { panic!() }
-//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+//~^ ERROR `impl Trait` not allowed outside of function and method return types
 
 // Disallowed
 fn in_Fn_return_in_generics<F: Fn() -> impl Debug> (_: F) { panic!() }
-//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+//~^ ERROR `impl Trait` not allowed outside of function and method return types
 
 
 // Allowed
@@ -80,22 +80,22 @@ fn in_impl_Trait_in_return() -> impl IntoIterator<Item = impl IntoIterator> {
 
 // Disallowed
 struct InBraceStructField { x: impl Debug }
-//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+//~^ ERROR `impl Trait` not allowed outside of function and method return types
 
 // Disallowed
 struct InAdtInBraceStructField { x: Vec<impl Debug> }
-//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+//~^ ERROR `impl Trait` not allowed outside of function and method return types
 
 // Disallowed
 struct InTupleStructField(impl Debug);
-//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+//~^ ERROR `impl Trait` not allowed outside of function and method return types
 
 // Disallowed
 enum InEnum {
     InBraceVariant { x: impl Debug },
-    //~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+    //~^ ERROR `impl Trait` not allowed outside of function and method return types
     InTupleVariant(impl Debug),
-    //~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+    //~^ ERROR `impl Trait` not allowed outside of function and method return types
 }
 
 // Allowed
@@ -106,7 +106,7 @@ trait InTraitDefnParameters {
 // Disallowed
 trait InTraitDefnReturn {
     fn in_return() -> impl Debug;
-    //~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+    //~^ ERROR `impl Trait` not allowed outside of function and method return types
 }
 
 // Allowed and disallowed in trait impls
@@ -123,7 +123,7 @@ fn in_trait_impl_parameter(_: impl Debug) { }
     // Allowed
 
     fn in_trait_impl_return() -> impl Debug { () }
-    //~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+    //~^ ERROR `impl Trait` not allowed outside of function and method return types
 }
 
 // Allowed
@@ -136,10 +136,10 @@ fn in_inherent_impl_return() -> impl Debug { () }
 // Disallowed
 extern "C" {
     fn in_foreign_parameters(_: impl Debug);
-    //~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+    //~^ ERROR `impl Trait` not allowed outside of function and method return types
 
     fn in_foreign_return() -> impl Debug;
-    //~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+    //~^ ERROR `impl Trait` not allowed outside of function and method return types
 }
 
 // Allowed
@@ -155,96 +155,96 @@ extern "C" fn in_extern_fn_return() -> impl Debug {
 //~^ ERROR `impl Trait` in type aliases is unstable
 
 type InReturnInTypeAlias<R> = fn() -> impl Debug;
-//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+//~^ ERROR `impl Trait` not allowed outside of function and method return types
 //~| ERROR `impl Trait` in type aliases is unstable
 
 // Disallowed in impl headers
 impl PartialEq<impl Debug> for () {
-    //~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+    //~^ ERROR `impl Trait` not allowed outside of function and method return types
 }
 
 // Disallowed in impl headers
 impl PartialEq<()> for impl Debug {
-    //~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+    //~^ ERROR `impl Trait` not allowed outside of function and method return types
 }
 
 // Disallowed in inherent impls
 impl impl Debug {
-    //~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+    //~^ ERROR `impl Trait` not allowed outside of function and method return types
 }
 
 // Disallowed in inherent impls
 struct InInherentImplAdt<T> { t: T }
 impl InInherentImplAdt<impl Debug> {
-    //~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+    //~^ ERROR `impl Trait` not allowed outside of function and method return types
 }
 
 // Disallowed in where clauses
 fn in_fn_where_clause()
     where impl Debug: Debug
-//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+//~^ ERROR `impl Trait` not allowed outside of function and method return types
 {
 }
 
 // Disallowed in where clauses
 fn in_adt_in_fn_where_clause()
     where Vec<impl Debug>: Debug
-//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+//~^ ERROR `impl Trait` not allowed outside of function and method return types
 {
 }
 
 // Disallowed
 fn in_trait_parameter_in_fn_where_clause<T>()
     where T: PartialEq<impl Debug>
-//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+//~^ ERROR `impl Trait` not allowed outside of function and method return types
 {
 }
 
 // Disallowed
 fn in_Fn_parameter_in_fn_where_clause<T>()
     where T: Fn(impl Debug)
-//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+//~^ ERROR `impl Trait` not allowed outside of function and method return types
 {
 }
 
 // Disallowed
 fn in_Fn_return_in_fn_where_clause<T>()
     where T: Fn() -> impl Debug
-//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+//~^ ERROR `impl Trait` not allowed outside of function and method return types
 {
 }
 
 // Disallowed
 struct InStructGenericParamDefault<T = impl Debug>(T);
-//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+//~^ ERROR `impl Trait` not allowed outside of function and method return types
 
 // Disallowed
 enum InEnumGenericParamDefault<T = impl Debug> { Variant(T) }
-//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+//~^ ERROR `impl Trait` not allowed outside of function and method return types
 
 // Disallowed
 trait InTraitGenericParamDefault<T = impl Debug> {}
-//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+//~^ ERROR `impl Trait` not allowed outside of function and method return types
 
 // Disallowed
 type InTypeAliasGenericParamDefault<T = impl Debug> = T;
-//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+//~^ ERROR `impl Trait` not allowed outside of function and method return types
 
 // Disallowed
 impl <T = impl Debug> T {}
 //~^ ERROR defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions
 //~| WARNING this was previously accepted by the compiler but is being phased out
-//~| ERROR `impl Trait` not allowed outside of function and inherent method return types
+//~| ERROR `impl Trait` not allowed outside of function and method return types
 
 // Disallowed
 fn in_method_generic_param_default<T = impl Debug>(_: T) {}
 //~^ ERROR defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions
 //~| WARNING this was previously accepted by the compiler but is being phased out
-//~| ERROR `impl Trait` not allowed outside of function and inherent method return types
+//~| ERROR `impl Trait` not allowed outside of function and method return types
 
 fn main() {
     let _in_local_variable: impl Fn() = || {};
-    //~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+    //~^ ERROR `impl Trait` not allowed outside of function and method return types
     let _in_return_in_local_variable = || -> impl Fn() { || {} };
-    //~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+    //~^ ERROR `impl Trait` not allowed outside of function and method return types
 }
index 09ec4d5b202c36a498414a771deb3cbc15455e54..93a3de61ccf8aeb2f79a8ccfb5aeb9a164cc9a11 100644 (file)
@@ -43,249 +43,247 @@ LL | type InReturnInTypeAlias<R> = fn() -> impl Debug;
    = note: see issue #63063 <https://github.com/rust-lang/rust/issues/63063> for more information
    = help: add `#![feature(min_type_alias_impl_trait)]` to the crate attributes to enable
 
-error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+error[E0562]: `impl Trait` not allowed outside of function and method return types
   --> $DIR/where-allowed.rs:15:40
    |
 LL | fn in_fn_parameter_in_parameters(_: fn(impl Debug)) { panic!() }
    |                                        ^^^^^^^^^^
 
-error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+error[E0562]: `impl Trait` not allowed outside of function and method return types
   --> $DIR/where-allowed.rs:19:42
    |
 LL | fn in_fn_return_in_parameters(_: fn() -> impl Debug) { panic!() }
    |                                          ^^^^^^^^^^
 
-error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+error[E0562]: `impl Trait` not allowed outside of function and method return types
   --> $DIR/where-allowed.rs:23:38
    |
 LL | fn in_fn_parameter_in_return() -> fn(impl Debug) { panic!() }
    |                                      ^^^^^^^^^^
 
-error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+error[E0562]: `impl Trait` not allowed outside of function and method return types
   --> $DIR/where-allowed.rs:27:40
    |
 LL | fn in_fn_return_in_return() -> fn() -> impl Debug { panic!() }
    |                                        ^^^^^^^^^^
 
-error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+error[E0562]: `impl Trait` not allowed outside of function and method return types
   --> $DIR/where-allowed.rs:31:49
    |
 LL | fn in_dyn_Fn_parameter_in_parameters(_: &dyn Fn(impl Debug)) { panic!() }
    |                                                 ^^^^^^^^^^
 
-error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+error[E0562]: `impl Trait` not allowed outside of function and method return types
   --> $DIR/where-allowed.rs:35:51
    |
 LL | fn in_dyn_Fn_return_in_parameters(_: &dyn Fn() -> impl Debug) { panic!() }
    |                                                   ^^^^^^^^^^
 
-error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+error[E0562]: `impl Trait` not allowed outside of function and method return types
   --> $DIR/where-allowed.rs:39:55
    |
 LL | fn in_dyn_Fn_parameter_in_return() -> &'static dyn Fn(impl Debug) { panic!() }
    |                                                       ^^^^^^^^^^
 
-error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+error[E0562]: `impl Trait` not allowed outside of function and method return types
   --> $DIR/where-allowed.rs:43:57
    |
 LL | fn in_dyn_Fn_return_in_return() -> &'static dyn Fn() -> impl Debug { panic!() }
    |                                                         ^^^^^^^^^^
 
-error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+error[E0562]: `impl Trait` not allowed outside of function and method return types
   --> $DIR/where-allowed.rs:47:51
    |
 LL | fn in_impl_Fn_parameter_in_parameters(_: &impl Fn(impl Debug)) { panic!() }
    |                                                   ^^^^^^^^^^
 
-error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+error[E0562]: `impl Trait` not allowed outside of function and method return types
   --> $DIR/where-allowed.rs:52:53
    |
 LL | fn in_impl_Fn_return_in_parameters(_: &impl Fn() -> impl Debug) { panic!() }
    |                                                     ^^^^^^^^^^
 
-error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+error[E0562]: `impl Trait` not allowed outside of function and method return types
   --> $DIR/where-allowed.rs:56:57
    |
 LL | fn in_impl_Fn_parameter_in_return() -> &'static impl Fn(impl Debug) { panic!() }
    |                                                         ^^^^^^^^^^
 
-error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+error[E0562]: `impl Trait` not allowed outside of function and method return types
   --> $DIR/where-allowed.rs:61:59
    |
 LL | fn in_impl_Fn_return_in_return() -> &'static impl Fn() -> impl Debug { panic!() }
    |                                                           ^^^^^^^^^^
 
-error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+error[E0562]: `impl Trait` not allowed outside of function and method return types
   --> $DIR/where-allowed.rs:65:38
    |
 LL | fn in_Fn_parameter_in_generics<F: Fn(impl Debug)> (_: F) { panic!() }
    |                                      ^^^^^^^^^^
 
-error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+error[E0562]: `impl Trait` not allowed outside of function and method return types
   --> $DIR/where-allowed.rs:69:40
    |
 LL | fn in_Fn_return_in_generics<F: Fn() -> impl Debug> (_: F) { panic!() }
    |                                        ^^^^^^^^^^
 
-error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+error[E0562]: `impl Trait` not allowed outside of function and method return types
   --> $DIR/where-allowed.rs:82:32
    |
 LL | struct InBraceStructField { x: impl Debug }
    |                                ^^^^^^^^^^
 
-error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+error[E0562]: `impl Trait` not allowed outside of function and method return types
   --> $DIR/where-allowed.rs:86:41
    |
 LL | struct InAdtInBraceStructField { x: Vec<impl Debug> }
    |                                         ^^^^^^^^^^
 
-error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+error[E0562]: `impl Trait` not allowed outside of function and method return types
   --> $DIR/where-allowed.rs:90:27
    |
 LL | struct InTupleStructField(impl Debug);
    |                           ^^^^^^^^^^
 
-error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+error[E0562]: `impl Trait` not allowed outside of function and method return types
   --> $DIR/where-allowed.rs:95:25
    |
 LL |     InBraceVariant { x: impl Debug },
    |                         ^^^^^^^^^^
 
-error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+error[E0562]: `impl Trait` not allowed outside of function and method return types
   --> $DIR/where-allowed.rs:97:20
    |
 LL |     InTupleVariant(impl Debug),
    |                    ^^^^^^^^^^
 
-error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+error[E0562]: `impl Trait` not allowed outside of function and method return types
   --> $DIR/where-allowed.rs:108:23
    |
 LL |     fn in_return() -> impl Debug;
    |                       ^^^^^^^^^^
 
-error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+error[E0562]: `impl Trait` not allowed outside of function and method return types
   --> $DIR/where-allowed.rs:125:34
    |
 LL |     fn in_trait_impl_return() -> impl Debug { () }
    |                                  ^^^^^^^^^^
 
-error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+error[E0562]: `impl Trait` not allowed outside of function and method return types
   --> $DIR/where-allowed.rs:138:33
    |
 LL |     fn in_foreign_parameters(_: impl Debug);
    |                                 ^^^^^^^^^^
 
-error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+error[E0562]: `impl Trait` not allowed outside of function and method return types
   --> $DIR/where-allowed.rs:141:31
    |
 LL |     fn in_foreign_return() -> impl Debug;
    |                               ^^^^^^^^^^
 
-error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+error[E0562]: `impl Trait` not allowed outside of function and method return types
   --> $DIR/where-allowed.rs:157:39
    |
 LL | type InReturnInTypeAlias<R> = fn() -> impl Debug;
    |                                       ^^^^^^^^^^
 
-error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+error[E0562]: `impl Trait` not allowed outside of function and method return types
   --> $DIR/where-allowed.rs:162:16
    |
 LL | impl PartialEq<impl Debug> for () {
    |                ^^^^^^^^^^
 
-error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+error[E0562]: `impl Trait` not allowed outside of function and method return types
   --> $DIR/where-allowed.rs:167:24
    |
 LL | impl PartialEq<()> for impl Debug {
    |                        ^^^^^^^^^^
 
-error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+error[E0562]: `impl Trait` not allowed outside of function and method return types
   --> $DIR/where-allowed.rs:172:6
    |
 LL | impl impl Debug {
    |      ^^^^^^^^^^
 
-error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+error[E0562]: `impl Trait` not allowed outside of function and method return types
   --> $DIR/where-allowed.rs:178:24
    |
 LL | impl InInherentImplAdt<impl Debug> {
    |                        ^^^^^^^^^^
 
-error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+error[E0562]: `impl Trait` not allowed outside of function and method return types
   --> $DIR/where-allowed.rs:184:11
    |
 LL |     where impl Debug: Debug
    |           ^^^^^^^^^^
 
-error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+error[E0562]: `impl Trait` not allowed outside of function and method return types
   --> $DIR/where-allowed.rs:191:15
    |
 LL |     where Vec<impl Debug>: Debug
    |               ^^^^^^^^^^
 
-error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+error[E0562]: `impl Trait` not allowed outside of function and method return types
   --> $DIR/where-allowed.rs:198:24
    |
 LL |     where T: PartialEq<impl Debug>
    |                        ^^^^^^^^^^
 
-error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+error[E0562]: `impl Trait` not allowed outside of function and method return types
   --> $DIR/where-allowed.rs:205:17
    |
 LL |     where T: Fn(impl Debug)
    |                 ^^^^^^^^^^
 
-error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+error[E0562]: `impl Trait` not allowed outside of function and method return types
   --> $DIR/where-allowed.rs:212:22
    |
 LL |     where T: Fn() -> impl Debug
    |                      ^^^^^^^^^^
 
-error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+error[E0562]: `impl Trait` not allowed outside of function and method return types
   --> $DIR/where-allowed.rs:218:40
    |
 LL | struct InStructGenericParamDefault<T = impl Debug>(T);
    |                                        ^^^^^^^^^^
 
-error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+error[E0562]: `impl Trait` not allowed outside of function and method return types
   --> $DIR/where-allowed.rs:222:36
    |
 LL | enum InEnumGenericParamDefault<T = impl Debug> { Variant(T) }
    |                                    ^^^^^^^^^^
 
-error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+error[E0562]: `impl Trait` not allowed outside of function and method return types
   --> $DIR/where-allowed.rs:226:38
    |
 LL | trait InTraitGenericParamDefault<T = impl Debug> {}
    |                                      ^^^^^^^^^^
 
-error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+error[E0562]: `impl Trait` not allowed outside of function and method return types
   --> $DIR/where-allowed.rs:230:41
    |
 LL | type InTypeAliasGenericParamDefault<T = impl Debug> = T;
    |                                         ^^^^^^^^^^
 
-error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+error[E0562]: `impl Trait` not allowed outside of function and method return types
   --> $DIR/where-allowed.rs:234:11
    |
 LL | impl <T = impl Debug> T {}
    |           ^^^^^^^^^^
 
-error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+error[E0562]: `impl Trait` not allowed outside of function and method return types
   --> $DIR/where-allowed.rs:240:40
    |
 LL | fn in_method_generic_param_default<T = impl Debug>(_: T) {}
    |                                        ^^^^^^^^^^
 
-error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+error[E0562]: `impl Trait` not allowed outside of function and method return types
   --> $DIR/where-allowed.rs:246:29
    |
 LL |     let _in_local_variable: impl Fn() = || {};
    |                             ^^^^^^^^^
-   |
-   = help: add `#![feature(impl_trait_in_bindings)]` to the crate attributes to enable
 
-error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+error[E0562]: `impl Trait` not allowed outside of function and method return types
   --> $DIR/where-allowed.rs:248:46
    |
 LL |     let _in_return_in_local_variable = || -> impl Fn() { || {} };
diff --git a/src/test/ui/inference/cannot-infer-async-enabled-impl-trait-bindings.rs b/src/test/ui/inference/cannot-infer-async-enabled-impl-trait-bindings.rs
deleted file mode 100644 (file)
index 7beb2db..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-// edition:2018
-#![feature(impl_trait_in_bindings)]
-//~^ WARN the feature `impl_trait_in_bindings` is incomplete
-
-use std::io::Error;
-
-fn make_unit() -> Result<(), Error> {
-    Ok(())
-}
-
-fn main() {
-    let fut = async {
-        make_unit()?;
-
-        Ok(()) //~ ERROR type annotations needed
-    };
-}
diff --git a/src/test/ui/inference/cannot-infer-async-enabled-impl-trait-bindings.stderr b/src/test/ui/inference/cannot-infer-async-enabled-impl-trait-bindings.stderr
deleted file mode 100644 (file)
index 8e632fb..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-warning: the feature `impl_trait_in_bindings` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/cannot-infer-async-enabled-impl-trait-bindings.rs:2:12
-   |
-LL | #![feature(impl_trait_in_bindings)]
-   |            ^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(incomplete_features)]` on by default
-   = note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
-
-error[E0282]: type annotations needed for `impl Future`
-  --> $DIR/cannot-infer-async-enabled-impl-trait-bindings.rs:15:9
-   |
-LL |     let fut = async {
-   |         --- consider giving `fut` the explicit type `impl Future`, where the type parameter `E` is specified
-...
-LL |         Ok(())
-   |         ^^ cannot infer type for type parameter `E` declared on the enum `Result`
-
-error: aborting due to previous error; 1 warning emitted
-
-For more information about this error, try `rustc --explain E0282`.
index 2a6e2414593aa4145e89f77dcf1bcd2ec92c7f19..9d181eab7fbcdf1cd51989d3143f792224b6b557 100644 (file)
@@ -45,6 +45,8 @@ error[E0726]: implicit elided lifetime not allowed here
    |
 LL | impl<'self> Serializable<str> for &'self str {
    |             ^^^^^^^^^^^^^^^^^ help: indicate the anonymous lifetime: `Serializable<'_, str>`
+   |
+   = note: assuming a `'static` lifetime...
 
 error[E0277]: the size for values of type `str` cannot be known at compilation time
   --> $DIR/issue-10412.rs:6:13
index 695d657cb529ca65e272d02b9a84d7d8a3939089..3b89e8bc451518b1714dfd14df5a1c5603977b25 100644 (file)
@@ -1,6 +1,8 @@
 error[E0308]: mismatched types
   --> $DIR/issue-12997-2.rs:8:1
    |
+LL | #[bench]
+   | -------- in this procedural macro expansion
 LL | fn bar(x: isize) { }
    | ^^^^^^^^^^^^^^^^^^^^ expected `isize`, found `&mut Bencher`
    |
index 69817f10c9f32c9c45663cc3581faec77601073b..ee1464fd8481105f4f87e2969c2dc80aaccaf7b2 100644 (file)
@@ -5,7 +5,11 @@ LL |     (|| Box::new(*(&[0][..])))();
    |                  ^^^^^^^^^^^ doesn't have a size known at compile-time
    |
    = help: the trait `Sized` is not implemented for `[{integer}]`
-   = note: required by `Box::<T>::new`
+note: required by `Box::<T>::new`
+  --> $SRC_DIR/alloc/src/boxed.rs:LL:COL
+   |
+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
index 8872f51753c94789fa0841a9a635e7d00c3fdfe2..0e942e80e254436dca5792928e63162bcb2811ef 100644 (file)
@@ -1,8 +1,11 @@
 error[E0277]: the trait bound `isize: HasState` is not satisfied
-  --> $DIR/issue-18611.rs:1:4
+  --> $DIR/issue-18611.rs:1:18
    |
 LL | fn add_state(op: <isize as HasState>::State) {
-   |    ^^^^^^^^^ the trait `HasState` is not implemented for `isize`
+   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `HasState` is not implemented for `isize`
+...
+LL | trait HasState {
+   | -------------- required by this bound in `HasState`
 
 error: aborting due to previous error
 
index 86b530e85a80ac8091e6d411ab9d1bf7fb9d5e34..2a5416ce85ba65e78140c4a40aaa85dce68c7338 100644 (file)
@@ -1,8 +1,8 @@
 error[E0038]: the trait `Bar` cannot be made into an object
-  --> $DIR/issue-18959.rs:11:11
+  --> $DIR/issue-18959.rs:11:12
    |
 LL | fn foo(b: &dyn Bar) {
-   |           ^^^^^^^^ `Bar` cannot be made into an object
+   |            ^^^^^^^ `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>
index 9940f43cc44404ce631f3d092015f4038da9edb5..25a90df45613b9b8e2777a9965c2b1b90c46f045 100644 (file)
@@ -6,7 +6,11 @@ LL |     for item in *things { *item = 0 }
    |
    = help: the trait `Sized` is not implemented for `dyn Iterator<Item = &'a mut u8>`
    = note: required because of the requirements on the impl of `IntoIterator` for `dyn Iterator<Item = &'a mut u8>`
-   = note: required by `into_iter`
+note: required by `into_iter`
+  --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
+   |
+LL |     fn into_iter(self) -> Self::IntoIter;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
index 4cef23ac42cb394c031dfedea09340b746ed30f7..c864381e6b0a629d9779de007a76361cefe74fec 100644 (file)
@@ -1,6 +1,8 @@
 error[E0277]: the trait bound `Bar: Hash` is not satisfied
   --> $DIR/issue-21160.rs:8:12
    |
+LL | #[derive(Hash)]
+   |          ---- in this derive macro expansion
 LL | struct Foo(Bar);
    |            ^^^ the trait `Hash` is not implemented for `Bar`
    | 
index 9b3b7a72e049eb617948574afc1b56569c564a70..47f28d7c443fcce61b15e9860a0f4659223d2eca 100644 (file)
@@ -3,6 +3,11 @@ error[E0624]: associated function `foo` is private
    |
 LL |         Foo::foo(&f);
    |              ^^^ private associated function
+   | 
+  ::: $DIR/auxiliary/issue-21202.rs:4:9
+   |
+LL |         fn foo(&self) { }
+   |         ------------- private associated function defined here
 
 error: aborting due to previous error
 
index 4c927a0cb458f8c471b52398a0a024de39b5350c..70caeb0ea39092578f8c7d32a234dfd8504f645f 100644 (file)
@@ -5,7 +5,11 @@ LL |     let _ = Iterator::next(&mut ());
    |                            ^^^^^^^ `()` is not an iterator
    |
    = help: the trait `Iterator` is not implemented for `()`
-   = note: required by `std::iter::Iterator::next`
+note: required by `std::iter::Iterator::next`
+  --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
+   |
+LL |     fn next(&mut self) -> Option<Self::Item>;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: `bool` is not an iterator
   --> $DIR/issue-28098.rs:6:14
@@ -15,7 +19,11 @@ LL |     for _ in false {}
    |
    = help: the trait `Iterator` is not implemented for `bool`
    = note: required because of the requirements on the impl of `IntoIterator` for `bool`
-   = note: required by `into_iter`
+note: required by `into_iter`
+  --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
+   |
+LL |     fn into_iter(self) -> Self::IntoIter;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: `()` is not an iterator
   --> $DIR/issue-28098.rs:9:28
@@ -24,7 +32,11 @@ LL |     let _ = Iterator::next(&mut ());
    |                            ^^^^^^^ `()` is not an iterator
    |
    = help: the trait `Iterator` is not implemented for `()`
-   = note: required by `std::iter::Iterator::next`
+note: required by `std::iter::Iterator::next`
+  --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
+   |
+LL |     fn next(&mut self) -> Option<Self::Item>;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: `()` is not an iterator
   --> $DIR/issue-28098.rs:2:13
@@ -41,7 +53,11 @@ LL |     let _ = Iterator::next(&mut ());
    |                            ^^^^^^^ `()` is not an iterator
    |
    = help: the trait `Iterator` is not implemented for `()`
-   = note: required by `std::iter::Iterator::next`
+note: required by `std::iter::Iterator::next`
+  --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
+   |
+LL |     fn next(&mut self) -> Option<Self::Item>;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: `()` is not an iterator
   --> $DIR/issue-28098.rs:22:28
@@ -50,7 +66,11 @@ LL |     let _ = Iterator::next(&mut ());
    |                            ^^^^^^^ `()` is not an iterator
    |
    = help: the trait `Iterator` is not implemented for `()`
-   = note: required by `std::iter::Iterator::next`
+note: required by `std::iter::Iterator::next`
+  --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
+   |
+LL |     fn next(&mut self) -> Option<Self::Item>;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: `bool` is not an iterator
   --> $DIR/issue-28098.rs:25:14
@@ -60,7 +80,11 @@ LL |     for _ in false {}
    |
    = help: the trait `Iterator` is not implemented for `bool`
    = note: required because of the requirements on the impl of `IntoIterator` for `bool`
-   = note: required by `into_iter`
+note: required by `into_iter`
+  --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
+   |
+LL |     fn into_iter(self) -> Self::IntoIter;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: `()` is not an iterator
   --> $DIR/issue-28098.rs:18:13
index 94aff5963544c59dd8d1cf566976ba31cebe8866..f00d5d32bbf28d6bc40fcfdb732e3cdebd512587 100644 (file)
@@ -1,13 +1,15 @@
 error[E0283]: type annotations needed
   --> $DIR/issue-29147.rs:21:13
    |
-LL | trait Foo { fn xxx(&self); }
-   |             -------------- required by `Foo::xxx`
-...
 LL |     let _ = <S5<_>>::xxx;
    |             ^^^^^^^^^^^^ cannot infer type for struct `S5<_>`
    |
    = note: cannot satisfy `S5<_>: Foo`
+note: required by `Foo::xxx`
+  --> $DIR/issue-29147.rs:10:13
+   |
+LL | trait Foo { fn xxx(&self); }
+   |             ^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
index 2d020188198af843ff55c811fd2f122c211fd24a..bc7eb0688ee84bb68bafa8803967f1f8b974b909 100644 (file)
@@ -8,7 +8,11 @@ LL |     Err(5)?;
    |
    = note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait
    = note: required because of the requirements on the impl of `FromResidual<Result<Infallible, {integer}>>` for `Result<i32, ()>`
-   = note: required by `from_residual`
+note: required by `from_residual`
+  --> $SRC_DIR/core/src/ops/try_trait.rs:LL:COL
+   |
+LL |     fn from_residual(residual: R) -> Self;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
index 043658c9508f3721a52cfa2746099d246eceedc9..d588214f5077c9f3d459e943bfd09d6e9e099c27 100644 (file)
@@ -17,7 +17,11 @@ LL |     for _ in HashMap::new().iter().cloned() {}
                   found tuple `(&_, &_)`
    = note: required because of the requirements on the impl of `Iterator` for `Cloned<std::collections::hash_map::Iter<'_, _, _>>`
    = note: required because of the requirements on the impl of `IntoIterator` for `Cloned<std::collections::hash_map::Iter<'_, _, _>>`
-   = note: required by `into_iter`
+note: required by `into_iter`
+  --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
+   |
+LL |     fn into_iter(self) -> Self::IntoIter;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0271]: type mismatch resolving `<std::collections::hash_map::Iter<'_, _, _> as Iterator>::Item == &_`
   --> $DIR/issue-33941.rs:4:14
@@ -28,7 +32,11 @@ LL |     for _ in HashMap::new().iter().cloned() {}
    = note: expected reference `&_`
                   found tuple `(&_, &_)`
    = note: required because of the requirements on the impl of `Iterator` for `Cloned<std::collections::hash_map::Iter<'_, _, _>>`
-   = note: required by `std::iter::Iterator::next`
+note: required by `std::iter::Iterator::next`
+  --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
+   |
+LL |     fn next(&mut self) -> Option<Self::Item>;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 3 previous errors
 
index c32fe7e0ec6238c910ac515007427f61ccccbf08..fba75de8cc0523f8c746178f738a838df4ee0b11 100644 (file)
@@ -2,10 +2,16 @@ error[E0277]: can't compare `Comparable` with `Comparable`
   --> $DIR/issue-34229.rs:2:46
    |
 LL | #[derive(PartialEq, PartialOrd)] struct Nope(Comparable);
-   |                                              ^^^^^^^^^^ no implementation for `Comparable < Comparable` and `Comparable > Comparable`
+   |                     ----------               ^^^^^^^^^^ no implementation for `Comparable < Comparable` and `Comparable > Comparable`
+   |                     |
+   |                     in this derive macro expansion
    |
    = help: the trait `PartialOrd` is not implemented for `Comparable`
-   = note: required by `std::cmp::PartialOrd::partial_cmp`
+note: required by `std::cmp::PartialOrd::partial_cmp`
+  --> $SRC_DIR/core/src/cmp.rs:LL:COL
+   |
+LL |     fn partial_cmp(&self, other: &Rhs) -> Option<Ordering>;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: this error originates in the derive macro `PartialOrd` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: aborting due to previous error
index 7f54c9f8a6b9ff9077bf8d7810f08a54f932985d..6f4567546d00b6a206282ac762f14af0b3080a6c 100644 (file)
@@ -13,12 +13,18 @@ LL |     let _woohoo = (Box::new(my_struct)).priv_field;
 error[E0624]: associated function `happyfun` is private
   --> $DIR/issue-3763.rs:24:18
    |
+LL |         fn happyfun(&self) {}
+   |         ------------------ private associated function defined here
+...
 LL |     (&my_struct).happyfun();
    |                  ^^^^^^^^ private associated function
 
 error[E0624]: associated function `happyfun` is private
   --> $DIR/issue-3763.rs:26:27
    |
+LL |         fn happyfun(&self) {}
+   |         ------------------ private associated function defined here
+...
 LL |     (Box::new(my_struct)).happyfun();
    |                           ^^^^^^^^ private associated function
 
index 2a0693a581c319e9f85706e8387e66a075367c7f..f609e47e818d493bfb9447be009384952c30f312 100644 (file)
@@ -1,9 +1,6 @@
 error[E0271]: type mismatch resolving `for<'a> <() as Array<'a>>::Element == ()`
   --> $DIR/issue-39970.rs:19:5
    |
-LL |     fn visit() {}
-   |     ---------- required by `Visit::visit`
-...
 LL |     <() as Visit>::visit();
    |     ^^^^^^^^^^^^^^^^^^^^ expected `()`, found `&()`
    |
@@ -12,6 +9,11 @@ note: required because of the requirements on the impl of `Visit` for `()`
    |
 LL | impl Visit for () where
    |      ^^^^^     ^^
+note: required by `Visit::visit`
+  --> $DIR/issue-39970.rs:6:5
+   |
+LL |     fn visit() {}
+   |     ^^^^^^^^^^
 
 error: aborting due to previous error
 
index 072243d881ca68f1507b631ef6f47cfb532f035f..c0208e680841eec256346603280c756516055d05 100644 (file)
@@ -1,19 +1,19 @@
 struct S;
 
 impl S {
-    #[derive(Debug)] //~ ERROR `derive` may only be applied to structs, enums and unions
+    #[derive(Debug)] //~ ERROR `derive` may only be applied to `struct`s, `enum`s and `union`s
     fn f() {
         file!();
     }
 }
 
 trait Tr1 {
-    #[derive(Debug)] //~ ERROR `derive` may only be applied to structs, enums and unions
+    #[derive(Debug)] //~ ERROR `derive` may only be applied to `struct`s, `enum`s and `union`s
     fn f();
 }
 
 trait Tr2 {
-    #[derive(Debug)] //~ ERROR `derive` may only be applied to structs, enums and unions
+    #[derive(Debug)] //~ ERROR `derive` may only be applied to `struct`s, `enum`s and `union`s
     type F;
 }
 
index f5f51cdcd4885a0bd8d7afdea6812f45f13b77c4..007eb259594704110e040ce39dd10a78f3505b9c 100644 (file)
@@ -1,20 +1,28 @@
-error[E0774]: `derive` may only be applied to structs, enums and unions
+error[E0774]: `derive` may only be applied to `struct`s, `enum`s and `union`s
   --> $DIR/issue-43023.rs:4:5
    |
-LL |     #[derive(Debug)]
-   |     ^^^^^^^^^^^^^^^^
+LL |       #[derive(Debug)]
+   |       ^^^^^^^^^^^^^^^^ not applicable here
+LL | /     fn f() {
+LL | |         file!();
+LL | |     }
+   | |_____- not a `struct`, `enum` or `union`
 
-error[E0774]: `derive` may only be applied to structs, enums and unions
+error[E0774]: `derive` may only be applied to `struct`s, `enum`s and `union`s
   --> $DIR/issue-43023.rs:11:5
    |
 LL |     #[derive(Debug)]
-   |     ^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^ not applicable here
+LL |     fn f();
+   |     ------- not a `struct`, `enum` or `union`
 
-error[E0774]: `derive` may only be applied to structs, enums and unions
+error[E0774]: `derive` may only be applied to `struct`s, `enum`s and `union`s
   --> $DIR/issue-43023.rs:16:5
    |
 LL |     #[derive(Debug)]
-   |     ^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^ not applicable here
+LL |     type F;
+   |     ------- not a `struct`, `enum` or `union`
 
 error: aborting due to 3 previous errors
 
index 80aca482b3d29b8c8e614353bd7e9f4360d02178..4bc5eb03e922cb26ffcf205feef26df4ed3467e4 100644 (file)
@@ -10,7 +10,7 @@ LL | {
 LL |     break_me::<Type, fn(_)>;
    |     ^^^^^^^^^^^^^^^^^^^^^^^
    |     |
-   |     expected signature of `fn(<Type as Trait<'b>>::Assoc) -> _`
+   |     expected signature of `for<'b> fn(<Type as Trait<'b>>::Assoc) -> _`
    |     found signature of `fn(()) -> _`
 
 error: aborting due to previous error
index 296de362db1b1a94154649a758713654b92db1de..63a28d997e11a04be36bc02d32df4544a2fc00f8 100644 (file)
@@ -1,22 +1,22 @@
-error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+error[E0562]: `impl Trait` not allowed outside of function and method return types
   --> $DIR/issue-47715.rs:9:37
    |
 LL | struct Container<T: Iterable<Item = impl Foo>> {
    |                                     ^^^^^^^^
 
-error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+error[E0562]: `impl Trait` not allowed outside of function and method return types
   --> $DIR/issue-47715.rs:14:30
    |
 LL | enum Enum<T: Iterable<Item = impl Foo>> {
    |                              ^^^^^^^^
 
-error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+error[E0562]: `impl Trait` not allowed outside of function and method return types
   --> $DIR/issue-47715.rs:19:32
    |
 LL | union Union<T: Iterable<Item = impl Foo> + Copy> {
    |                                ^^^^^^^^
 
-error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+error[E0562]: `impl Trait` not allowed outside of function and method return types
   --> $DIR/issue-47715.rs:24:30
    |
 LL | type Type<T: Iterable<Item = impl Foo>> = T;
index ec73e670634df943a1ccb10684d0d493d120d022..119d84a068859f1ad043cd85533063160af0d9ec 100644 (file)
@@ -7,24 +7,24 @@ fn main() {
     struct Foo;
 
     // fold_stmt (Mac)
-    #[derive(Debug)] //~ ERROR `derive` may only be applied to structs, enums and unions
+    #[derive(Debug)] //~ ERROR `derive` may only be applied to `struct`s, `enum`s and `union`s
     println!("Hello, world!");
 
     // fold_stmt (Semi)
-    #[derive(Debug)] //~ ERROR `derive` may only be applied to structs, enums and unions
+    #[derive(Debug)] //~ ERROR `derive` may only be applied to `struct`s, `enum`s and `union`s
     "Hello, world!";
 
     // fold_stmt (Local)
-    #[derive(Debug)] //~ ERROR `derive` may only be applied to structs, enums and unions
+    #[derive(Debug)] //~ ERROR `derive` may only be applied to `struct`s, `enum`s and `union`s
     let _ = "Hello, world!";
 
     // visit_expr
     let _ = #[derive(Debug)] "Hello, world!";
-    //~^ ERROR `derive` may only be applied to structs, enums and unions
+    //~^ ERROR `derive` may only be applied to `struct`s, `enum`s and `union`s
 
     let _ = [
         // filter_map_expr
-        #[derive(Debug)] //~ ERROR `derive` may only be applied to structs, enums and unions
+        #[derive(Debug)] //~ ERROR `derive` may only be applied to `struct`s, `enum`s and `union`s
         "Hello, world!",
     ];
 }
index 7746ad287ab796f945677e5e92d13c1b7a0da827..f2ff541bb9925026215b068ea5c113467cee182d 100644 (file)
@@ -1,32 +1,42 @@
-error[E0774]: `derive` may only be applied to structs, enums and unions
+error[E0774]: `derive` may only be applied to `struct`s, `enum`s and `union`s
   --> $DIR/issue-49934.rs:10:5
    |
 LL |     #[derive(Debug)]
-   |     ^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^ not applicable here
+LL |     println!("Hello, world!");
+   |     -------------------------- not a `struct`, `enum` or `union`
 
-error[E0774]: `derive` may only be applied to structs, enums and unions
+error[E0774]: `derive` may only be applied to `struct`s, `enum`s and `union`s
   --> $DIR/issue-49934.rs:14:5
    |
 LL |     #[derive(Debug)]
-   |     ^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^ not applicable here
+LL |     "Hello, world!";
+   |     ---------------- not a `struct`, `enum` or `union`
 
-error[E0774]: `derive` may only be applied to structs, enums and unions
+error[E0774]: `derive` may only be applied to `struct`s, `enum`s and `union`s
   --> $DIR/issue-49934.rs:18:5
    |
 LL |     #[derive(Debug)]
-   |     ^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^ not applicable here
+LL |     let _ = "Hello, world!";
+   |     ------------------------ not a `struct`, `enum` or `union`
 
-error[E0774]: `derive` may only be applied to structs, enums and unions
+error[E0774]: `derive` may only be applied to `struct`s, `enum`s and `union`s
   --> $DIR/issue-49934.rs:22:13
    |
 LL |     let _ = #[derive(Debug)] "Hello, world!";
-   |             ^^^^^^^^^^^^^^^^
+   |             ^^^^^^^^^^^^^^^^ --------------- not a `struct`, `enum` or `union`
+   |             |
+   |             not applicable here
 
-error[E0774]: `derive` may only be applied to structs, enums and unions
+error[E0774]: `derive` may only be applied to `struct`s, `enum`s and `union`s
   --> $DIR/issue-49934.rs:27:9
    |
 LL |         #[derive(Debug)]
-   |         ^^^^^^^^^^^^^^^^
+   |         ^^^^^^^^^^^^^^^^ not applicable here
+LL |         "Hello, world!",
+   |         --------------- not a `struct`, `enum` or `union`
 
 error: aborting due to 5 previous errors
 
index 3c0f7f2b55026e6eda83f5b5be03b040d8e69884..b28fbff62b907f6569c61b5ac100e76a0e7125f6 100644 (file)
@@ -1,6 +1,9 @@
 error[E0624]: associated function `foo` is private
   --> $DIR/issue-53498.rs:16:27
    |
+LL |         fn foo() {}
+   |         -------- private associated function defined here
+...
 LL |     test::Foo::<test::B>::foo();
    |                           ^^^ private associated function
 
index fb31467ec47fa356adc951b8c6ece17c7d8bc380..a1715bd99e094c8bdd9373465c0dcc157a8bd0e7 100644 (file)
@@ -7,9 +7,6 @@ LL |         Foo(Box::new(*slice))
 error[E0283]: type annotations needed
   --> $DIR/issue-58022.rs:4:25
    |
-LL |     const SIZE: usize;
-   |     ------------------ required by `Foo::SIZE`
-LL | 
 LL |     fn new(slice: &[u8; Foo::SIZE]) -> Self;
    |                         ^^^^^^^^^
    |                         |
@@ -18,6 +15,11 @@ LL |     fn new(slice: &[u8; Foo::SIZE]) -> Self;
    |
    = note: cannot satisfy `_: Foo`
    = note: associated constants cannot be accessed directly on a `trait`, they can only be accessed through a specific `impl`
+note: required by `Foo::SIZE`
+  --> $DIR/issue-58022.rs:2:5
+   |
+LL |     const SIZE: usize;
+   |     ^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 2 previous errors
 
index 650570b6471eb13266ce99e8273e68350eaaf272..149562f8fb31c7e61d832fc8e1e9fcf1c2350628 100644 (file)
@@ -10,7 +10,7 @@ LL |     F: for<'a> FnMut(<T as Trait<'a>>::Item),
 LL |     foo((), drop)
    |             ^^^^
    |             |
-   |             expected signature of `fn(<() as Trait<'a>>::Item) -> _`
+   |             expected signature of `for<'a> fn(<() as Trait<'a>>::Item) -> _`
    |             found signature of `fn(()) -> _`
 
 error[E0277]: the size for values of type `<() as Trait<'_>>::Item` cannot be known at compilation time
index 8fd50300ca63e7d1c7967fad26f02916c857eeec..59a521c7360faaefb8e8ab376e301e9b12c69756 100644 (file)
@@ -7,11 +7,14 @@ LL |     _Func::< <() as _A>::AssocT >::func(());
 error[E0277]: the trait bound `(): _Func<_>` is not satisfied
   --> $DIR/issue-66353.rs:12:41
    |
-LL |     fn func(_: Self);
-   |     ----------------- required by `_Func::func`
-...
 LL |     _Func::< <() as _A>::AssocT >::func(());
    |                                         ^^ the trait `_Func<_>` is not implemented for `()`
+   |
+note: required by `_Func::func`
+  --> $DIR/issue-66353.rs:4:5
+   |
+LL |     fn func(_: Self);
+   |     ^^^^^^^^^^^^^^^^^
 
 error: aborting due to 2 previous errors
 
index 3443cca5f327058695df5f7bde8e9d57eb726164..af3459a7d2d6fec7194d42c57f85009d3acfc8d3 100644 (file)
@@ -5,7 +5,11 @@ LL |     String::from("x".as_ref());
    |     ^^^^^^^^^^^^ cannot infer type for reference `&_`
    |
    = note: cannot satisfy `String: From<&_>`
-   = note: required by `from`
+note: required by `from`
+  --> $SRC_DIR/core/src/convert/mod.rs:LL:COL
+   |
+LL |     fn from(_: T) -> Self;
+   |     ^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0282]: type annotations needed
   --> $DIR/issue-72690.rs:11:6
@@ -30,7 +34,11 @@ LL |     String::from("x".as_ref());
    |     ^^^^^^^^^^^^ cannot infer type for reference `&_`
    |
    = note: cannot satisfy `String: From<&_>`
-   = note: required by `from`
+note: required by `from`
+  --> $SRC_DIR/core/src/convert/mod.rs:LL:COL
+   |
+LL |     fn from(_: T) -> Self;
+   |     ^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0283]: type annotations needed
   --> $DIR/issue-72690.rs:25:5
@@ -39,7 +47,11 @@ LL |     String::from("x".as_ref());
    |     ^^^^^^^^^^^^ cannot infer type for reference `&_`
    |
    = note: cannot satisfy `String: From<&_>`
-   = note: required by `from`
+note: required by `from`
+  --> $SRC_DIR/core/src/convert/mod.rs:LL:COL
+   |
+LL |     fn from(_: T) -> Self;
+   |     ^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0283]: type annotations needed
   --> $DIR/issue-72690.rs:33:5
@@ -48,7 +60,11 @@ LL |     String::from("x".as_ref());
    |     ^^^^^^^^^^^^ cannot infer type for reference `&_`
    |
    = note: cannot satisfy `String: From<&_>`
-   = note: required by `from`
+note: required by `from`
+  --> $SRC_DIR/core/src/convert/mod.rs:LL:COL
+   |
+LL |     fn from(_: T) -> Self;
+   |     ^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0283]: type annotations needed
   --> $DIR/issue-72690.rs:41:5
@@ -57,7 +73,11 @@ LL |     String::from("x".as_ref());
    |     ^^^^^^^^^^^^ cannot infer type for reference `&_`
    |
    = note: cannot satisfy `String: From<&_>`
-   = note: required by `from`
+note: required by `from`
+  --> $SRC_DIR/core/src/convert/mod.rs:LL:COL
+   |
+LL |     fn from(_: T) -> Self;
+   |     ^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0283]: type annotations needed
   --> $DIR/issue-72690.rs:47:5
@@ -66,7 +86,11 @@ LL |     String::from("x".as_ref());
    |     ^^^^^^^^^^^^ cannot infer type for reference `&_`
    |
    = note: cannot satisfy `String: From<&_>`
-   = note: required by `from`
+note: required by `from`
+  --> $SRC_DIR/core/src/convert/mod.rs:LL:COL
+   |
+LL |     fn from(_: T) -> Self;
+   |     ^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0283]: type annotations needed
   --> $DIR/issue-72690.rs:55:5
@@ -75,7 +99,11 @@ LL |     String::from("x".as_ref());
    |     ^^^^^^^^^^^^ cannot infer type for reference `&_`
    |
    = note: cannot satisfy `String: From<&_>`
-   = note: required by `from`
+note: required by `from`
+  --> $SRC_DIR/core/src/convert/mod.rs:LL:COL
+   |
+LL |     fn from(_: T) -> Self;
+   |     ^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 9 previous errors
 
diff --git a/src/test/ui/issues/issue-87199.rs b/src/test/ui/issues/issue-87199.rs
new file mode 100644 (file)
index 0000000..a80a64a
--- /dev/null
@@ -0,0 +1,20 @@
+// Regression test for issue #87199, where attempting to relax a bound
+// other than the only supported `?Sized` would still cause the compiler
+// to assume that the `Sized` bound was relaxed.
+
+// check-fail
+
+// Check that these function definitions only emit warnings, not errors
+fn arg<T: ?Send>(_: T) {}
+//~^ warning: default bound relaxed for a type parameter, but this does nothing
+fn ref_arg<T: ?Send>(_: &T) {}
+//~^ warning: default bound relaxed for a type parameter, but this does nothing
+fn ret() -> impl Iterator<Item = ()> + ?Send { std::iter::empty() }
+//~^ warning: default bound relaxed for a type parameter, but this does nothing
+
+// Check that there's no `?Sized` relaxation!
+fn main() {
+    ref_arg::<i32>(&5);
+    ref_arg::<[i32]>(&[5]);
+    //~^ the size for values of type `[i32]` cannot be known
+}
diff --git a/src/test/ui/issues/issue-87199.stderr b/src/test/ui/issues/issue-87199.stderr
new file mode 100644 (file)
index 0000000..e3a8e82
--- /dev/null
@@ -0,0 +1,36 @@
+warning: default bound relaxed for a type parameter, but this does nothing because the given bound is not a default; only `?Sized` is supported
+  --> $DIR/issue-87199.rs:8:8
+   |
+LL | fn arg<T: ?Send>(_: T) {}
+   |        ^
+
+warning: default bound relaxed for a type parameter, but this does nothing because the given bound is not a default; only `?Sized` is supported
+  --> $DIR/issue-87199.rs:10:12
+   |
+LL | fn ref_arg<T: ?Send>(_: &T) {}
+   |            ^
+
+warning: default bound relaxed for a type parameter, but this does nothing because the given bound is not a default; only `?Sized` is supported
+  --> $DIR/issue-87199.rs:12:13
+   |
+LL | fn ret() -> impl Iterator<Item = ()> + ?Send { std::iter::empty() }
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0277]: the size for values of type `[i32]` cannot be known at compilation time
+  --> $DIR/issue-87199.rs:18:22
+   |
+LL | fn ref_arg<T: ?Send>(_: &T) {}
+   |            - required by this bound in `ref_arg`
+...
+LL |     ref_arg::<[i32]>(&[5]);
+   |                      ^^^^ doesn't have a size known at compile-time
+   |
+   = help: the trait `Sized` is not implemented for `[i32]`
+help: consider relaxing the implicit `Sized` restriction
+   |
+LL | fn ref_arg<T: ?Send + ?Sized>(_: &T) {}
+   |                     ^^^^^^^^
+
+error: aborting due to previous error; 3 warnings emitted
+
+For more information about this error, try `rustc --explain E0277`.
index e31ee59785c8b7ff48691be11a61a3fe184b661a..60b2cbfdf4592f2ddcf24fef389c88d49ad2530a 100644 (file)
@@ -7,7 +7,11 @@ LL |     for _ in 42 {}
    = help: the trait `Iterator` is not implemented for `{integer}`
    = note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end`
    = note: required because of the requirements on the impl of `IntoIterator` for `{integer}`
-   = note: required by `into_iter`
+note: required by `into_iter`
+  --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
+   |
+LL |     fn into_iter(self) -> Self::IntoIter;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: `u8` is not an iterator
   --> $DIR/integral.rs:4:14
@@ -18,7 +22,11 @@ LL |     for _ in 42 as u8 {}
    = help: the trait `Iterator` is not implemented for `u8`
    = note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end`
    = note: required because of the requirements on the impl of `IntoIterator` for `u8`
-   = note: required by `into_iter`
+note: required by `into_iter`
+  --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
+   |
+LL |     fn into_iter(self) -> Self::IntoIter;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: `i8` is not an iterator
   --> $DIR/integral.rs:6:14
@@ -29,7 +37,11 @@ LL |     for _ in 42 as i8 {}
    = help: the trait `Iterator` is not implemented for `i8`
    = note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end`
    = note: required because of the requirements on the impl of `IntoIterator` for `i8`
-   = note: required by `into_iter`
+note: required by `into_iter`
+  --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
+   |
+LL |     fn into_iter(self) -> Self::IntoIter;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: `u16` is not an iterator
   --> $DIR/integral.rs:8:14
@@ -40,7 +52,11 @@ LL |     for _ in 42 as u16 {}
    = help: the trait `Iterator` is not implemented for `u16`
    = note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end`
    = note: required because of the requirements on the impl of `IntoIterator` for `u16`
-   = note: required by `into_iter`
+note: required by `into_iter`
+  --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
+   |
+LL |     fn into_iter(self) -> Self::IntoIter;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: `i16` is not an iterator
   --> $DIR/integral.rs:10:14
@@ -51,7 +67,11 @@ LL |     for _ in 42 as i16 {}
    = help: the trait `Iterator` is not implemented for `i16`
    = note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end`
    = note: required because of the requirements on the impl of `IntoIterator` for `i16`
-   = note: required by `into_iter`
+note: required by `into_iter`
+  --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
+   |
+LL |     fn into_iter(self) -> Self::IntoIter;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: `u32` is not an iterator
   --> $DIR/integral.rs:12:14
@@ -62,7 +82,11 @@ LL |     for _ in 42 as u32 {}
    = help: the trait `Iterator` is not implemented for `u32`
    = note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end`
    = note: required because of the requirements on the impl of `IntoIterator` for `u32`
-   = note: required by `into_iter`
+note: required by `into_iter`
+  --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
+   |
+LL |     fn into_iter(self) -> Self::IntoIter;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: `i32` is not an iterator
   --> $DIR/integral.rs:14:14
@@ -73,7 +97,11 @@ LL |     for _ in 42 as i32 {}
    = help: the trait `Iterator` is not implemented for `i32`
    = note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end`
    = note: required because of the requirements on the impl of `IntoIterator` for `i32`
-   = note: required by `into_iter`
+note: required by `into_iter`
+  --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
+   |
+LL |     fn into_iter(self) -> Self::IntoIter;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: `u64` is not an iterator
   --> $DIR/integral.rs:16:14
@@ -84,7 +112,11 @@ LL |     for _ in 42 as u64 {}
    = help: the trait `Iterator` is not implemented for `u64`
    = note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end`
    = note: required because of the requirements on the impl of `IntoIterator` for `u64`
-   = note: required by `into_iter`
+note: required by `into_iter`
+  --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
+   |
+LL |     fn into_iter(self) -> Self::IntoIter;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: `i64` is not an iterator
   --> $DIR/integral.rs:18:14
@@ -95,7 +127,11 @@ LL |     for _ in 42 as i64 {}
    = help: the trait `Iterator` is not implemented for `i64`
    = note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end`
    = note: required because of the requirements on the impl of `IntoIterator` for `i64`
-   = note: required by `into_iter`
+note: required by `into_iter`
+  --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
+   |
+LL |     fn into_iter(self) -> Self::IntoIter;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: `usize` is not an iterator
   --> $DIR/integral.rs:20:14
@@ -106,7 +142,11 @@ LL |     for _ in 42 as usize {}
    = help: the trait `Iterator` is not implemented for `usize`
    = note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end`
    = note: required because of the requirements on the impl of `IntoIterator` for `usize`
-   = note: required by `into_iter`
+note: required by `into_iter`
+  --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
+   |
+LL |     fn into_iter(self) -> Self::IntoIter;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: `isize` is not an iterator
   --> $DIR/integral.rs:22:14
@@ -117,7 +157,11 @@ LL |     for _ in 42 as isize {}
    = help: the trait `Iterator` is not implemented for `isize`
    = note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end`
    = note: required because of the requirements on the impl of `IntoIterator` for `isize`
-   = note: required by `into_iter`
+note: required by `into_iter`
+  --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
+   |
+LL |     fn into_iter(self) -> Self::IntoIter;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: `{float}` is not an iterator
   --> $DIR/integral.rs:24:14
@@ -127,7 +171,11 @@ LL |     for _ in 42.0 {}
    |
    = help: the trait `Iterator` is not implemented for `{float}`
    = note: required because of the requirements on the impl of `IntoIterator` for `{float}`
-   = note: required by `into_iter`
+note: required by `into_iter`
+  --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
+   |
+LL |     fn into_iter(self) -> Self::IntoIter;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 12 previous errors
 
index 73844329e361d5d69c8773d8bae997318df9aa3e..fdc33862c0aba1392f72c2c9d5e0fdcc6a7ea261 100644 (file)
@@ -7,7 +7,11 @@ LL |     for _ in ..10 {}
    = help: the trait `Iterator` is not implemented for `RangeTo<{integer}>`
    = note: `..end` is a `RangeTo`, which cannot be iterated on; you might have meant to have a bounded `Range`: `0..end`
    = note: required because of the requirements on the impl of `IntoIterator` for `RangeTo<{integer}>`
-   = note: required by `into_iter`
+note: required by `into_iter`
+  --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
+   |
+LL |     fn into_iter(self) -> Self::IntoIter;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: `RangeToInclusive<{integer}>` is not an iterator
   --> $DIR/ranges.rs:4:14
@@ -18,7 +22,11 @@ LL |     for _ in ..=10 {}
    = help: the trait `Iterator` is not implemented for `RangeToInclusive<{integer}>`
    = note: `..=end` is a `RangeToInclusive`, which cannot be iterated on; you might have meant to have a bounded `RangeInclusive`: `0..=end`
    = note: required because of the requirements on the impl of `IntoIterator` for `RangeToInclusive<{integer}>`
-   = note: required by `into_iter`
+note: required by `into_iter`
+  --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
+   |
+LL |     fn into_iter(self) -> Self::IntoIter;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 2 previous errors
 
index 1d77bcb753630f860ce28fd2999e59ce91a3751e..f7089be2772968ce60112912f3ead2fcd4f14375 100644 (file)
@@ -6,7 +6,11 @@ LL |     for _ in "".to_owned() {}
    |
    = help: the trait `Iterator` is not implemented for `String`
    = note: required because of the requirements on the impl of `IntoIterator` for `String`
-   = note: required by `into_iter`
+note: required by `into_iter`
+  --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
+   |
+LL |     fn into_iter(self) -> Self::IntoIter;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: `&str` is not an iterator
   --> $DIR/string.rs:4:14
@@ -16,7 +20,11 @@ LL |     for _ in "" {}
    |
    = help: the trait `Iterator` is not implemented for `&str`
    = note: required because of the requirements on the impl of `IntoIterator` for `&str`
-   = note: required by `into_iter`
+note: required by `into_iter`
+  --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
+   |
+LL |     fn into_iter(self) -> Self::IntoIter;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/lint/cli-lint-override.forbid_warn.stderr b/src/test/ui/lint/cli-lint-override.forbid_warn.stderr
new file mode 100644 (file)
index 0000000..ff4dc4a
--- /dev/null
@@ -0,0 +1,11 @@
+error: extern declarations without an explicit ABI are deprecated
+  --> $DIR/cli-lint-override.rs:12:1
+   |
+LL | extern fn foo() {}
+   | ^^^^^^^^^^^^^^^ ABI should be specified here
+   |
+   = note: requested on the command line with `-F missing-abi`
+   = help: the default ABI is C
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/lint/cli-lint-override.force_warn_deny.stderr b/src/test/ui/lint/cli-lint-override.force_warn_deny.stderr
new file mode 100644 (file)
index 0000000..74e7823
--- /dev/null
@@ -0,0 +1,11 @@
+warning: extern declarations without an explicit ABI are deprecated
+  --> $DIR/cli-lint-override.rs:12:1
+   |
+LL | extern fn foo() {}
+   | ^^^^^^^^^^^^^^^ ABI should be specified here
+   |
+   = note: requested on the command line with `--force-warn missing-abi`
+   = help: the default ABI is C
+
+warning: 1 warning emitted
+
diff --git a/src/test/ui/lint/cli-lint-override.rs b/src/test/ui/lint/cli-lint-override.rs
new file mode 100644 (file)
index 0000000..a0a96d0
--- /dev/null
@@ -0,0 +1,17 @@
+// Tests that subsequent lints specified via the command line override
+// each other, except for ForceWarn and Forbid, which cannot be overriden.
+//
+// revisions: warn_deny forbid_warn force_warn_deny
+//
+//[warn_deny] compile-flags: --warn missing_abi --deny missing_abi
+//[forbid_warn] compile-flags: --warn missing_abi --forbid missing_abi
+//[force_warn_deny] compile-flags: -Z unstable-options --force-warn missing_abi --allow missing_abi
+//[force_warn_deny] check-pass
+
+
+extern fn foo() {}
+//[warn_deny]~^ ERROR extern declarations without an explicit ABI are deprecated
+//[forbid_warn]~^^ ERROR extern declarations without an explicit ABI are deprecated
+//[force_warn_deny]~^^^ WARN extern declarations without an explicit ABI are deprecated
+
+fn main() {}
diff --git a/src/test/ui/lint/cli-lint-override.warn_deny.stderr b/src/test/ui/lint/cli-lint-override.warn_deny.stderr
new file mode 100644 (file)
index 0000000..2d869ad
--- /dev/null
@@ -0,0 +1,11 @@
+error: extern declarations without an explicit ABI are deprecated
+  --> $DIR/cli-lint-override.rs:12:1
+   |
+LL | extern fn foo() {}
+   | ^^^^^^^^^^^^^^^ ABI should be specified here
+   |
+   = note: requested on the command line with `-D missing-abi`
+   = help: the default ABI is C
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/lint/cli-unknown-force-warn.rs b/src/test/ui/lint/cli-unknown-force-warn.rs
new file mode 100644 (file)
index 0000000..55544cc
--- /dev/null
@@ -0,0 +1,7 @@
+// Checks that rustc correctly errors when passed an invalid lint with
+// `--force-warn`. This is a regression test for issue #86958.
+//
+// compile-flags: -Z unstable-options --force-warn foo-qux
+// error-pattern: unknown lint: `foo_qux`
+
+fn main() {}
diff --git a/src/test/ui/lint/cli-unknown-force-warn.stderr b/src/test/ui/lint/cli-unknown-force-warn.stderr
new file mode 100644 (file)
index 0000000..4367c3b
--- /dev/null
@@ -0,0 +1,15 @@
+error[E0602]: unknown lint: `foo_qux`
+   |
+   = note: requested on the command line with `--force-warn foo_qux`
+
+error[E0602]: unknown lint: `foo_qux`
+   |
+   = note: requested on the command line with `--force-warn foo_qux`
+
+error[E0602]: unknown lint: `foo_qux`
+   |
+   = note: requested on the command line with `--force-warn foo_qux`
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0602`.
index 0a3e20b4f7d66dbff56971c0fd45df3f1dec2659..4799429ea2c69317f6e084e84fd4ccea37578160 100644 (file)
@@ -1,4 +1,4 @@
-// compile-flags: --force-warns elided_lifetimes_in_paths -Zunstable-options
+// compile-flags: --force-warn elided_lifetimes_in_paths -Zunstable-options
 // check-pass
 
 struct Foo<'a> {
index 37c61e614f3e338f2a9db94d16fb7e851ac5d142..05513de81d1c85c521b2c14027bd6ac37c150c6e 100644 (file)
@@ -4,7 +4,7 @@ warning: hidden lifetime parameters in types are deprecated
 LL | fn foo(x: &Foo) {}
    |            ^^^- help: indicate the anonymous lifetime: `<'_>`
    |
-   = note: requested on the command line with `--force-warns elided-lifetimes-in-paths`
+   = note: requested on the command line with `--force-warn elided-lifetimes-in-paths`
 
 warning: 1 warning emitted
 
index 0abc49137269d93e6a7f5d0d9a8e472e3b0e6e1b..d066feba86984c99395a78b7460a7cf032d77637 100644 (file)
@@ -1,4 +1,4 @@
-// compile-flags: --force-warns const_err -Zunstable-options
+// compile-flags: --force-warn const_err -Zunstable-options
 // check-pass
 
 #![allow(const_err)]
index 56b2f0236a5d373c4f037e0eef314b98141fc011..dd4f88a3b533ee90579ab13a6527e9e7e291bf1b 100644 (file)
@@ -6,7 +6,7 @@ LL | const C: i32 = 1 / 0;
    |                |
    |                attempt to divide `1_i32` by zero
    |
-   = note: requested on the command line with `--force-warns const-err`
+   = note: requested on the command line with `--force-warn const-err`
    = 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 #71800 <https://github.com/rust-lang/rust/issues/71800>
 
index bac0e4f8f8e866559d19e08e9c1d033b9ecb6c9f..280de5064720ae7deb70d6aa5fbbcb0ada2121e7 100644 (file)
@@ -1,4 +1,4 @@
-// compile-flags: --force-warns dead_code -Zunstable-options
+// compile-flags: --force-warn dead_code -Zunstable-options
 // check-pass
 
 #![allow(dead_code)]
index 7eb980a129708d8f4e2bc562d9463bb1f767ff1e..fced147254e82483f9b8bd4e45986a6299eebb3b 100644 (file)
@@ -4,7 +4,7 @@ warning: function is never used: `dead_function`
 LL | fn dead_function() {}
    |    ^^^^^^^^^^^^^
    |
-   = note: requested on the command line with `--force-warns dead-code`
+   = note: requested on the command line with `--force-warn dead-code`
 
 warning: 1 warning emitted
 
index e721760ab2da0a4785e80012eba114842b88b063..8331df02da7637de159e97e103736641747aa0c5 100644 (file)
@@ -1,4 +1,4 @@
-// compile-flags: --force-warns const_err -Zunstable-options
+// compile-flags: --force-warn const_err -Zunstable-options
 // check-pass
 
 const C: i32 = 1 / 0;
index 8b9bb5a74cfc10762a0174b8f8849d5ac7640515..68cd3a392f5830c6db2bdf4426ff38811c62d9dd 100644 (file)
@@ -6,7 +6,7 @@ LL | const C: i32 = 1 / 0;
    |                |
    |                attempt to divide `1_i32` by zero
    |
-   = note: requested on the command line with `--force-warns const-err`
+   = note: requested on the command line with `--force-warn const-err`
    = 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 #71800 <https://github.com/rust-lang/rust/issues/71800>
 
index 0dc1ce28ac4f5f2e8f42fb00d3d81aa276160d4d..0e8a65a41173d050e599a47acbd8dfbc69aa5597 100644 (file)
@@ -1,4 +1,4 @@
-// compile-flags: --force-warns dead_code -Zunstable-options
+// compile-flags: --force-warn dead_code -Zunstable-options
 // check-pass
 
 #![allow(warnings)]
index ebdb022f2a20b05770ff6b0f5805beaff854ff44..3305f2c02834d7571ef7024e20d65a47b2dada84 100644 (file)
@@ -4,7 +4,7 @@ warning: function is never used: `dead_function`
 LL | fn dead_function() {}
    |    ^^^^^^^^^^^^^
    |
-   = note: requested on the command line with `--force-warns dead-code`
+   = note: requested on the command line with `--force-warn dead-code`
 
 warning: 1 warning emitted
 
index 4f637c7fefa2b873670b3e7d5f5dc81cf0b5f643..aaca59a2a2aabba9700515c49dad81d9d10dc33d 100644 (file)
@@ -1,4 +1,4 @@
-// compile-flags: --force-warns nonstandard_style -Zunstable-options
+// compile-flags: --force-warn nonstandard_style -Zunstable-options
 // check-pass
 
 #![allow(warnings)]
index 7429e77fe83e11aae881ec46aca12eb86b4d634e..065a8f6a556a0d9613c857af8b9abb897a2fa2d4 100644 (file)
@@ -4,7 +4,7 @@ warning: function `FUNCTION` should have a snake case name
 LL | pub fn FUNCTION() {}
    |        ^^^^^^^^ help: convert the identifier to snake case: `function`
    |
-   = note: `--force-warns non-snake-case` implied by `--force-warns nonstandard-style`
+   = note: `--force-warn non-snake-case` implied by `--force-warn nonstandard-style`
 
 warning: 1 warning emitted
 
index b4c2c505aa560dae2499c2955ceeaf34b866e038..d8447bd23824440ca3140732cf9f0b9f338af1f3 100644 (file)
@@ -1,4 +1,4 @@
-// compile-flags: --force-warns bare_trait_objects -Zunstable-options
+// compile-flags: --force-warn bare_trait_objects -Zunstable-options
 // check-pass
 
 #![allow(rust_2018_idioms)]
index 4f7bba6bba1c9fdb5b5e282350631ec323432c18..185c0e8e3d0eba88105739eb1e0821a59ba31dd5 100644 (file)
@@ -4,7 +4,7 @@ warning: trait objects without an explicit `dyn` are deprecated
 LL | pub fn function(_x: Box<SomeTrait>) {}
    |                         ^^^^^^^^^ help: use `dyn`: `dyn SomeTrait`
    |
-   = note: requested on the command line with `--force-warns bare-trait-objects`
+   = note: requested on the command line with `--force-warn bare-trait-objects`
    = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see issue #80165 <https://github.com/rust-lang/rust/issues/80165>
 
diff --git a/src/test/ui/lint/force-warn/force-warn-cap-lints-allow.rs b/src/test/ui/lint/force-warn/force-warn-cap-lints-allow.rs
new file mode 100644 (file)
index 0000000..e10d161
--- /dev/null
@@ -0,0 +1,10 @@
+// compile-flags: --cap-lints allow  --force-warn bare_trait_objects -Zunstable-options
+// check-pass
+
+pub trait SomeTrait {}
+
+pub fn function(_x: Box<SomeTrait>) {}
+//~^ WARN trait objects without an explicit `dyn` are deprecated
+//~| WARN this is accepted in the current edition
+
+fn main() {}
diff --git a/src/test/ui/lint/force-warn/force-warn-cap-lints-allow.stderr b/src/test/ui/lint/force-warn/force-warn-cap-lints-allow.stderr
new file mode 100644 (file)
index 0000000..a899705
--- /dev/null
@@ -0,0 +1,12 @@
+warning: trait objects without an explicit `dyn` are deprecated
+  --> $DIR/force-warn-cap-lints-allow.rs:6:25
+   |
+LL | pub fn function(_x: Box<SomeTrait>) {}
+   |                         ^^^^^^^^^ help: use `dyn`: `dyn SomeTrait`
+   |
+   = note: requested on the command line with `--force-warn bare-trait-objects`
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
+   = note: for more information, see issue #80165 <https://github.com/rust-lang/rust/issues/80165>
+
+warning: 1 warning emitted
+
index bcfe6e5a5bd6e8a4b61bee859b3d59b6d5933ba0..4afc0868608d389ef1fee5cbc761da280c3babb5 100644 (file)
@@ -1,4 +1,4 @@
-// compile-flags: --cap-lints warn  --force-warns rust-2021-compatibility -Zunstable-options
+// compile-flags: --cap-lints warn  --force-warn rust-2021-compatibility -Zunstable-options
 // check-pass
 #![allow(ellipsis_inclusive_range_patterns)]
 
index 07e786ce7d2663745aac2ab0dfb9c7b5c52d5afe..1d5f88086c5c410c97bb0a6d79bcae15e42e27cc 100644 (file)
@@ -4,7 +4,7 @@ warning: `...` range patterns are deprecated
 LL |         0...100 => true,
    |          ^^^ help: use `..=` for an inclusive range
    |
-   = note: `--force-warns ellipsis-inclusive-range-patterns` implied by `--force-warns rust-2021-compatibility`
+   = note: `--force-warn ellipsis-inclusive-range-patterns` implied by `--force-warn rust-2021-compatibility`
    = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see issue #80165 <https://github.com/rust-lang/rust/issues/80165>
 
index 83a1c078f062f5bec33de0fe76f30c9b3f5bfa6a..193ba2b6f0da52bbeb597cb0d4443a5c383b0dd6 100644 (file)
@@ -1,4 +1,4 @@
-// compile-flags: --force-warns rust-2018-idioms -Zunstable-options
+// compile-flags: --force-warn rust-2018-idioms -Zunstable-options
 // check-pass
 
 #![allow(bare_trait_objects)]
index 65de6c9e287f0045f52a30c7ae0efe9b77aba8d2..d242ef266b8d1a2e2f36ceeef1dd0225927086fe 100644 (file)
@@ -4,7 +4,7 @@ warning: trait objects without an explicit `dyn` are deprecated
 LL | pub fn function(_x: Box<SomeTrait>) {}
    |                         ^^^^^^^^^ help: use `dyn`: `dyn SomeTrait`
    |
-   = note: `--force-warns bare-trait-objects` implied by `--force-warns rust-2018-idioms`
+   = note: `--force-warn bare-trait-objects` implied by `--force-warn rust-2018-idioms`
    = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see issue #80165 <https://github.com/rust-lang/rust/issues/80165>
 
index 5e5fda973d54e7fcfd7234e61151b88d84f3e7c9..0198610b78e10c8e8fecb7a94588a324c6cf2804 100644 (file)
@@ -1,4 +1,4 @@
-// compile-flags: --force-warns rust_2018_idioms -Zunstable-options
+// compile-flags: --force-warn rust_2018_idioms -Zunstable-options
 // check-pass
 
 #![allow(rust_2018_idioms)]
index fd3397c916a6dc9c3580f1ac35f8576ece1ba685..180dff880a65828356280598b923880db57b1045 100644 (file)
@@ -4,7 +4,7 @@ warning: trait objects without an explicit `dyn` are deprecated
 LL | pub fn function(_x: Box<SomeTrait>) {}
    |                         ^^^^^^^^^ help: use `dyn`: `dyn SomeTrait`
    |
-   = note: `--force-warns bare-trait-objects` implied by `--force-warns rust-2018-idioms`
+   = note: `--force-warn bare-trait-objects` implied by `--force-warn rust-2018-idioms`
    = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see issue #80165 <https://github.com/rust-lang/rust/issues/80165>
 
diff --git a/src/test/ui/lint/force-warn/force-warns-cap-lints-allow.rs b/src/test/ui/lint/force-warn/force-warns-cap-lints-allow.rs
deleted file mode 100644 (file)
index e364897..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-// compile-flags: --cap-lints allow  --force-warns bare_trait_objects -Zunstable-options
-// check-pass
-
-pub trait SomeTrait {}
-
-pub fn function(_x: Box<SomeTrait>) {}
-//~^ WARN trait objects without an explicit `dyn` are deprecated
-//~| WARN this is accepted in the current edition
-
-fn main() {}
diff --git a/src/test/ui/lint/force-warn/force-warns-cap-lints-allow.stderr b/src/test/ui/lint/force-warn/force-warns-cap-lints-allow.stderr
deleted file mode 100644 (file)
index 2153202..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-warning: trait objects without an explicit `dyn` are deprecated
-  --> $DIR/force-warns-cap-lints-allow.rs:6:25
-   |
-LL | pub fn function(_x: Box<SomeTrait>) {}
-   |                         ^^^^^^^^^ help: use `dyn`: `dyn SomeTrait`
-   |
-   = note: requested on the command line with `--force-warns bare-trait-objects`
-   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
-   = note: for more information, see issue #80165 <https://github.com/rust-lang/rust/issues/80165>
-
-warning: 1 warning emitted
-
diff --git a/src/test/ui/lint/issue-87274-paren-parent.rs b/src/test/ui/lint/issue-87274-paren-parent.rs
new file mode 100644 (file)
index 0000000..0141c5a
--- /dev/null
@@ -0,0 +1,9 @@
+// check-pass
+// Tests that we properly lint at 'paren' expressions
+
+fn foo() -> Result<(), String>  {
+    (try!(Ok::<u8, String>(1))); //~ WARN use of deprecated macro `try`
+    Ok(())
+}
+
+fn main() {}
diff --git a/src/test/ui/lint/issue-87274-paren-parent.stderr b/src/test/ui/lint/issue-87274-paren-parent.stderr
new file mode 100644 (file)
index 0000000..f060242
--- /dev/null
@@ -0,0 +1,10 @@
+warning: use of deprecated macro `try`: use the `?` operator instead
+  --> $DIR/issue-87274-paren-parent.rs:5:6
+   |
+LL |     (try!(Ok::<u8, String>(1)));
+   |      ^^^
+   |
+   = note: `#[warn(deprecated)]` on by default
+
+warning: 1 warning emitted
+
index c36a8b2a4bf8c39babdc14570940cc9e8b4cd9d8..2d842d5142097e0eb37596f0e86744e582c8ecc6 100644 (file)
@@ -6,4 +6,8 @@
                    //~| HELP did you mean
                    //~| SUGGESTION dead_code
 
+#![deny(rust_2018_idiots)] //~ ERROR unknown lint
+                           //~| HELP did you mean
+                           //~| SUGGESTION rust_2018_idioms
+
 fn main() {}
index 3a102769e855b4696df7e0567cf184ad42f71fa7..0cb6b49578cf30490bbe0426d6c4ed0554dde053 100644 (file)
@@ -16,5 +16,11 @@ error: unknown lint: `dead_cod`
 LL | #![deny(dead_cod)]
    |         ^^^^^^^^ help: did you mean: `dead_code`
 
-error: aborting due to 2 previous errors
+error: unknown lint: `rust_2018_idiots`
+  --> $DIR/lint-unknown-lint.rs:9:9
+   |
+LL | #![deny(rust_2018_idiots)]
+   |         ^^^^^^^^^^^^^^^^ help: did you mean: `rust_2018_idioms`
+
+error: aborting due to 3 previous errors
 
index 5a8e2f50ce33d2fbca03f7f73da240fbe2c3e520..b2fdd2e1965818fbb2543551d1e88f21dc10e6a7 100644 (file)
@@ -39,5 +39,5 @@ fn main() {
 #[my_macro]
 fn use_bang_macro_as_attr() {}
 
-#[derive(Debug)] //~ ERROR `derive` may only be applied to structs
+#[derive(Debug)] //~ ERROR `derive` may only be applied to `struct`s
 fn use_derive_macro_as_attr() {}
index 96e7d61398b7e052230f3fe2ecbc2ee3c1d00164..38affde5f6c3301ac07522fe34fea420cb56c99b 100644 (file)
@@ -60,11 +60,13 @@ LL |     let a = pat_macro!();
    |
    = note: this error originates in the macro `pat_macro` (in Nightly builds, run with -Z macro-backtrace for more info)
 
-error[E0774]: `derive` may only be applied to structs, enums and unions
+error[E0774]: `derive` may only be applied to `struct`s, `enum`s and `union`s
   --> $DIR/trace_faulty_macros.rs:42:1
    |
 LL | #[derive(Debug)]
-   | ^^^^^^^^^^^^^^^^
+   | ^^^^^^^^^^^^^^^^ not applicable here
+LL | fn use_derive_macro_as_attr() {}
+   | -------------------------------- not a `struct`, `enum` or `union`
 
 note: trace_macro
   --> $DIR/trace_faulty_macros.rs:36:13
index aff19094b7af8c2ed24eaddf7cce01eed9fc0d0d..543d15fadc6be78762074d7186b385c7aee5db45 100644 (file)
@@ -7,15 +7,11 @@ LL | #![cfg_attr(full_tait, feature(type_alias_impl_trait))]
    = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #63063 <https://github.com/rust-lang/rust/issues/63063> for more information
 
-error[E0658]: type alias impl trait is not permitted here
-  --> $DIR/issue-75053.rs:52:15
+error: fatal error triggered by #[rustc_error]
+  --> $DIR/issue-75053.rs:49:1
    |
-LL |     let _pos: Phantom1<DummyT<()>> = Scope::new().my_index();
-   |               ^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
-   = help: add `#![feature(impl_trait_in_bindings)]` to the crate attributes to enable
+LL | fn main() {
+   | ^^^^^^^^^
 
 error: aborting due to previous error; 1 warning emitted
 
-For more information about this error, try `rustc --explain E0658`.
index a43fabc8f5d91a55fcd31109a15117f9f607c446..d75996bf0b3ae3615b4c9bdab12390bdcd4ba889 100644 (file)
@@ -1,24 +1,11 @@
-warning: the feature `impl_trait_in_bindings` is incomplete and may not be safe to use and/or cause compiler crashes
+error[E0557]: feature has been removed
   --> $DIR/issue-75053.rs:7:34
    |
 LL | #![cfg_attr(in_bindings, feature(impl_trait_in_bindings))]
-   |                                  ^^^^^^^^^^^^^^^^^^^^^^
+   |                                  ^^^^^^^^^^^^^^^^^^^^^^ feature has been removed
    |
-   = note: `#[warn(incomplete_features)]` on by default
-   = note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
+   = note: removed due to being incomplete and unstable
 
-error[E0282]: type annotations needed
-  --> $DIR/issue-75053.rs:52:38
-   |
-LL |     type O;
-   |     ------- `<Self as MyIndex<T>>::O` defined here
-...
-LL |     let _pos: Phantom1<DummyT<()>> = Scope::new().my_index();
-   |                                      ^^^^^^^^^^-------------
-   |                                      |
-   |                                      this method call resolves to `<Self as MyIndex<T>>::O`
-   |                                      cannot infer type for type parameter `T`
-
-error: aborting due to previous error; 1 warning emitted
+error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0282`.
+For more information about this error, try `rustc --explain E0557`.
index 7ce91e851a755399783e5fee7a53ce54ea051681..c533275c99a79554657bdf219d9e567b90c8fc79 100644 (file)
@@ -1,12 +1,8 @@
-error[E0658]: type alias impl trait is not permitted here
-  --> $DIR/issue-75053.rs:52:15
+error: fatal error triggered by #[rustc_error]
+  --> $DIR/issue-75053.rs:49:1
    |
-LL |     let _pos: Phantom1<DummyT<()>> = Scope::new().my_index();
-   |               ^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
-   = help: add `#![feature(impl_trait_in_bindings)]` to the crate attributes to enable
+LL | fn main() {
+   | ^^^^^^^^^
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0658`.
index 89ae3ca3006b951ff22de0c6d506ff64903a623f..b71f84dd9c24ef730bd79afb21a5324ab194e4e7 100644 (file)
@@ -1,11 +1,9 @@
 // compile-flags: -Z mir-opt-level=3
 
-// revisions: min_tait full_tait in_bindings
+// revisions: min_tait full_tait
 #![feature(min_type_alias_impl_trait, rustc_attrs)]
 #![cfg_attr(full_tait, feature(type_alias_impl_trait))]
 //[full_tait]~^ WARN incomplete
-#![cfg_attr(in_bindings, feature(impl_trait_in_bindings))]
-//[in_bindings]~^ WARN incomplete
 
 use std::marker::PhantomData;
 
@@ -49,7 +47,6 @@ fn my_index(self) -> Self::O {
 
 #[rustc_error]
 fn main() {
+    //~^ ERROR
     let _pos: Phantom1<DummyT<()>> = Scope::new().my_index();
-    //[min_tait,full_tait]~^ ERROR not permitted here
-    //[in_bindings]~^^ ERROR type annotations needed
 }
index f0651c4cdef0e33d10d316d2372c9b4d6ea30627..804b6282202be85cd9082d4bab3c18233cbcca47 100644 (file)
@@ -1,35 +1,41 @@
 error[E0277]: the trait bound `[i32]: Index<u32>` is not satisfied
   --> $DIR/multiple-impls.rs:33:18
    |
-LL |     fn index(&self, index: Idx) -> &Self::Output;
-   |     --------------------------------------------- required by `Index::index`
-...
 LL |     Index::index(&[] as &[i32], 2u32);
    |                  ^^^^^^^^^^^^^ trait message
    |
    = help: the trait `Index<u32>` is not implemented for `[i32]`
+note: required by `Index::index`
+  --> $DIR/multiple-impls.rs:12:5
+   |
+LL |     fn index(&self, index: Idx) -> &Self::Output;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `[i32]: Index<Foo<u32>>` is not satisfied
   --> $DIR/multiple-impls.rs:36:18
    |
-LL |     fn index(&self, index: Idx) -> &Self::Output;
-   |     --------------------------------------------- required by `Index::index`
-...
 LL |     Index::index(&[] as &[i32], Foo(2u32));
    |                  ^^^^^^^^^^^^^ on impl for Foo
    |
    = help: the trait `Index<Foo<u32>>` is not implemented for `[i32]`
+note: required by `Index::index`
+  --> $DIR/multiple-impls.rs:12:5
+   |
+LL |     fn index(&self, index: Idx) -> &Self::Output;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `[i32]: Index<Bar<u32>>` is not satisfied
   --> $DIR/multiple-impls.rs:39:18
    |
-LL |     fn index(&self, index: Idx) -> &Self::Output;
-   |     --------------------------------------------- required by `Index::index`
-...
 LL |     Index::index(&[] as &[i32], Bar(2u32));
    |                  ^^^^^^^^^^^^^ on impl for Bar
    |
    = help: the trait `Index<Bar<u32>>` is not implemented for `[i32]`
+note: required by `Index::index`
+  --> $DIR/multiple-impls.rs:12:5
+   |
+LL |     fn index(&self, index: Idx) -> &Self::Output;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `[i32]: Index<u32>` is not satisfied
   --> $DIR/multiple-impls.rs:33:5
index f19fa8a07fe64822caf26969934b8da5f303caaf..bfd438e5cc215212efa3983cd252901ce12a56fc 100644 (file)
@@ -1,13 +1,15 @@
 error[E0277]: the trait bound `[i32]: Index<u32>` is not satisfied
   --> $DIR/on-impl.rs:22:25
    |
-LL |     fn index(&self, index: Idx) -> &Self::Output;
-   |     --------------------------------------------- required by `Index::index`
-...
 LL |     Index::<u32>::index(&[1, 2, 3] as &[i32], 2u32);
    |                         ^^^^^^^^^^^^^^^^^^^^ a usize is required to index into a slice
    |
    = help: the trait `Index<u32>` is not implemented for `[i32]`
+note: required by `Index::index`
+  --> $DIR/on-impl.rs:9:5
+   |
+LL |     fn index(&self, index: Idx) -> &Self::Output;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `[i32]: Index<u32>` is not satisfied
   --> $DIR/on-impl.rs:22:5
index fe9c113710c3c09f71508f7d0a14ff50977dbcdf..5c229431ad34cc2c0edb378e30498ba04142a37d 100644 (file)
@@ -25,7 +25,11 @@ LL | |     }.hi() {
    |
    = help: the trait `Iterator` is not implemented for `bool`
    = note: required because of the requirements on the impl of `IntoIterator` for `bool`
-   = note: required by `into_iter`
+note: required by `into_iter`
+  --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
+   |
+LL |     fn into_iter(self) -> Self::IntoIter;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/pattern/issue-71042-opaquely-typed-constant-used-in-pattern.rs b/src/test/ui/pattern/issue-71042-opaquely-typed-constant-used-in-pattern.rs
deleted file mode 100644 (file)
index 65f27cf..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-#![feature(impl_trait_in_bindings)]
-#![allow(incomplete_features)]
-
-fn main() {
-    const C: impl Copy = 0;
-    match C {
-        C | //~ ERROR: `impl Copy` cannot be used in patterns
-        _ => {}
-    }
-}
diff --git a/src/test/ui/pattern/issue-71042-opaquely-typed-constant-used-in-pattern.stderr b/src/test/ui/pattern/issue-71042-opaquely-typed-constant-used-in-pattern.stderr
deleted file mode 100644 (file)
index 62dc856..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-error: `impl Copy` cannot be used in patterns
-  --> $DIR/issue-71042-opaquely-typed-constant-used-in-pattern.rs:7:9
-   |
-LL |         C |
-   |         ^
-
-error: aborting due to previous error
-
index 65c10a7bca75deba5dc98673354130e2d2d1f361..70e6fcb7a07ed2409e7ad8b6f0cae030a0acc69f 100644 (file)
@@ -157,30 +157,45 @@ LL |     trait B {
 error[E0624]: associated function `bar` is private
   --> $DIR/privacy1.rs:77:23
    |
+LL |             fn bar() {}
+   |             -------- private associated function defined here
+...
 LL |         self::baz::A::bar();
    |                       ^^^ private associated function
 
 error[E0624]: associated function `bar` is private
   --> $DIR/privacy1.rs:95:13
    |
+LL |         fn bar() {}
+   |         -------- private associated function defined here
+...
 LL |     bar::A::bar();
    |             ^^^ private associated function
 
 error[E0624]: associated function `bar` is private
   --> $DIR/privacy1.rs:102:19
    |
+LL |         fn bar() {}
+   |         -------- private associated function defined here
+...
 LL |         ::bar::A::bar();
    |                   ^^^ private associated function
 
 error[E0624]: associated function `bar` is private
   --> $DIR/privacy1.rs:105:24
    |
+LL |             fn bar() {}
+   |             -------- private associated function defined here
+...
 LL |         ::bar::baz::A::bar();
    |                        ^^^ private associated function
 
 error[E0624]: associated function `bar2` is private
   --> $DIR/privacy1.rs:108:23
    |
+LL |             fn bar2(&self) {}
+   |             -------------- private associated function defined here
+...
 LL |         ::bar::baz::A.bar2();
    |                       ^^^^ private associated function
 
index 444b9180b3f5977334777f201560760d100b870b..bb54dce7e7e05d4d08e827dfbbfabe08f2c22dd4 100644 (file)
@@ -1,6 +1,9 @@
 error[E0624]: associated function `foo` is private
   --> $DIR/private-impl-method.rs:20:7
    |
+LL |         fn foo(&self) {}
+   |         ------------- private associated function defined here
+...
 LL |     s.foo();
    |       ^^^ private associated function
 
index 8a47846d667e34c8a687e190979e33c3b9f644b4..65329329933635e1e52aea8b8e627fcb230d12f2 100644 (file)
@@ -3,6 +3,11 @@ error[E0624]: associated function `nap` is private
    |
 LL |   nyan.nap();
    |        ^^^ private associated function
+   | 
+  ::: $DIR/auxiliary/cci_class_5.rs:8:9
+   |
+LL |         fn nap(&self) {}
+   |         ------------- private associated function defined here
 
 error: aborting due to previous error
 
index 8083b197a5d78e0facf8b1a24de0f87a0e80adb1..011a7fee478a65b35e1f6fc0e42f5671d9f00fdd 100644 (file)
@@ -1,6 +1,9 @@
 error[E0624]: associated function `f` is private
   --> $DIR/private-method-inherited.rs:13:7
    |
+LL |         fn f(self) {}
+   |         ---------- private associated function defined here
+...
 LL |     x.f();
    |       ^ private associated function
 
index a15fce46877ceb8c3e35cefc43f96a16a97dabdb..17c7179dc3684ed53186edb50a13f6f020c1281d 100644 (file)
@@ -1,6 +1,9 @@
 error[E0624]: associated function `nap` is private
   --> $DIR/private-method.rs:22:8
    |
+LL |         fn nap(&self) {}
+   |         ------------- private associated function defined here
+...
 LL |   nyan.nap();
    |        ^^^ private associated function
 
index 61b9a43f899f9c5fc87cbeeb7969883083ffe67d..6950667f1ea0ba6810c373afdef82cac1f9c1a6b 100644 (file)
@@ -55,12 +55,18 @@ LL |     S::default().x;
 error[E0624]: associated function `f` is private
   --> $DIR/test.rs:32:18
    |
+LL |             pub(super) fn f(&self) {}
+   |             ---------------------- private associated function defined here
+...
 LL |     S::default().f();
    |                  ^ private associated function
 
 error[E0624]: associated function `g` is private
   --> $DIR/test.rs:33:8
    |
+LL |             pub(super) fn g() {}
+   |             ----------------- private associated function defined here
+...
 LL |     S::g();
    |        ^ private associated function
 
@@ -81,12 +87,22 @@ error[E0624]: associated function `g` is private
    |
 LL |     u.g();
    |       ^ private associated function
+   | 
+  ::: $DIR/auxiliary/pub_restricted.rs:14:5
+   |
+LL |     pub(crate) fn g(&self) {}
+   |     ---------------------- private associated function defined here
 
 error[E0624]: associated function `h` is private
   --> $DIR/test.rs:46:7
    |
 LL |     u.h();
    |       ^ private associated function
+   | 
+  ::: $DIR/auxiliary/pub_restricted.rs:15:5
+   |
+LL |     crate fn h(&self) {}
+   |     ----------------- private associated function defined here
 
 error: aborting due to 12 previous errors
 
index c506e903e7f897b7f2ebac04210e0c15615b0a59..6c30e8f4f9558da2a9a3265d1d77c45bea2e0ed6 100644 (file)
@@ -13,7 +13,7 @@ mod m {
 struct Y;
 type A = X; //~ ERROR cannot find type `X` in this scope
 
-#[derive(Copy)] //~ ERROR `derive` may only be applied to structs, enums and unions
+#[derive(Copy)] //~ ERROR `derive` may only be applied to `struct`s, `enum`s and `union`s
 mod n {}
 
 #[empty_attr]
index 7141a1b50b570538c371d5d8387089e1792bb7fd..bb6cbb6984d7c1dd30072f73fda3db31a1fd31ea 100644 (file)
@@ -1,8 +1,10 @@
-error[E0774]: `derive` may only be applied to structs, enums and unions
+error[E0774]: `derive` may only be applied to `struct`s, `enum`s and `union`s
   --> $DIR/attributes-on-modules-fail.rs:16:1
    |
 LL | #[derive(Copy)]
-   | ^^^^^^^^^^^^^^^
+   | ^^^^^^^^^^^^^^^ not applicable here
+LL | mod n {}
+   | -------- not a `struct`, `enum` or `union`
 
 error[E0658]: non-inline modules in proc macro input are unstable
   --> $DIR/attributes-on-modules-fail.rs:20:1
index e52bf435a1244f2dc20f5881d7714e63f4c79c50..c8b26b00597dee378dfe5fa38e8bf793307a3031 100644 (file)
@@ -1,5 +1,5 @@
 extern "C" {
-    #[derive(Copy)] //~ ERROR `derive` may only be applied to structs, enums and unions
+    #[derive(Copy)] //~ ERROR `derive` may only be applied to `struct`s, `enum`s and `union`s
     fn f();
 }
 
index 6b73744920931e2406fd6da35287c2a48974f7d2..efd9ff22506ce1b82e7af512486380fdf26d834b 100644 (file)
@@ -1,8 +1,10 @@
-error[E0774]: `derive` may only be applied to structs, enums and unions
+error[E0774]: `derive` may only be applied to `struct`s, `enum`s and `union`s
   --> $DIR/macros-in-extern-derive.rs:2:5
    |
 LL |     #[derive(Copy)]
-   |     ^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^ not applicable here
+LL |     fn f();
+   |     ------- not a `struct`, `enum` or `union`
 
 error: aborting due to previous error
 
index 9152ee60a7ed46a51d127250f69a7e9f9ad1442f..c3904d62c8df38c0ce536e8594f0bca9bc54ffa0 100644 (file)
@@ -10,7 +10,7 @@ LL |             field: MissingType
   ::: $DIR/span-from-proc-macro.rs:8:1
    |
 LL | #[error_from_attribute]
-   | ----------------------- in this macro invocation
+   | ----------------------- in this procedural macro expansion
 
 error[E0412]: cannot find type `OtherMissingType` in this scope
   --> $DIR/auxiliary/span-from-proc-macro.rs:46:21
@@ -24,7 +24,7 @@ LL |             Variant(OtherMissingType)
   ::: $DIR/span-from-proc-macro.rs:11:10
    |
 LL | #[derive(ErrorFromDerive)]
-   |          --------------- in this macro invocation
+   |          --------------- in this derive macro expansion
 
 error[E0425]: cannot find value `my_ident` in this scope
   --> $DIR/auxiliary/span-from-proc-macro.rs:29:9
index 2cebffec990f69177bf04e22d444b57824682c25..b282fa7803f03a119cc1b5eb0b3c88975f1a3da2 100644 (file)
@@ -12,7 +12,11 @@ LL |     for i in false..true {}
    |
    = note: required because of the requirements on the impl of `Iterator` for `std::ops::Range<bool>`
    = note: required because of the requirements on the impl of `IntoIterator` for `std::ops::Range<bool>`
-   = note: required by `into_iter`
+note: required by `into_iter`
+  --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
+   |
+LL |     fn into_iter(self) -> Self::IntoIter;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the size for values of type `[{integer}]` cannot be known at compilation time
   --> $DIR/range-1.rs:14:17
index bc4c9a04b5e4b3aff82dc4c45dbe8362763a5f8a..34c59fcb318a99df40f6829fc7d5d2fdea7ea3b2 100644 (file)
 error[E0277]: can't compare `std::ops::Range<usize>` with `std::ops::Range<usize>`
   --> $DIR/range_traits-1.rs:5:5
    |
+LL | #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
+   |                                ---------- in this derive macro expansion
+LL | struct AllTheRanges {
 LL |     a: Range<usize>,
    |     ^^^^^^^^^^^^^^^ no implementation for `std::ops::Range<usize> < std::ops::Range<usize>` and `std::ops::Range<usize> > std::ops::Range<usize>`
    |
    = help: the trait `PartialOrd` is not implemented for `std::ops::Range<usize>`
-   = note: required by `std::cmp::PartialOrd::partial_cmp`
+note: required by `std::cmp::PartialOrd::partial_cmp`
+  --> $SRC_DIR/core/src/cmp.rs:LL:COL
+   |
+LL |     fn partial_cmp(&self, other: &Rhs) -> Option<Ordering>;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: this error originates in the derive macro `PartialOrd` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0277]: can't compare `std::ops::RangeTo<usize>` with `std::ops::RangeTo<usize>`
   --> $DIR/range_traits-1.rs:8:5
    |
+LL | #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
+   |                                ---------- in this derive macro expansion
+...
 LL |     b: RangeTo<usize>,
    |     ^^^^^^^^^^^^^^^^^ no implementation for `std::ops::RangeTo<usize> < std::ops::RangeTo<usize>` and `std::ops::RangeTo<usize> > std::ops::RangeTo<usize>`
    |
    = help: the trait `PartialOrd` is not implemented for `std::ops::RangeTo<usize>`
-   = note: required by `std::cmp::PartialOrd::partial_cmp`
+note: required by `std::cmp::PartialOrd::partial_cmp`
+  --> $SRC_DIR/core/src/cmp.rs:LL:COL
+   |
+LL |     fn partial_cmp(&self, other: &Rhs) -> Option<Ordering>;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: this error originates in the derive macro `PartialOrd` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0277]: can't compare `std::ops::RangeFrom<usize>` with `std::ops::RangeFrom<usize>`
   --> $DIR/range_traits-1.rs:11:5
    |
+LL | #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
+   |                                ---------- in this derive macro expansion
+...
 LL |     c: RangeFrom<usize>,
    |     ^^^^^^^^^^^^^^^^^^^ no implementation for `std::ops::RangeFrom<usize> < std::ops::RangeFrom<usize>` and `std::ops::RangeFrom<usize> > std::ops::RangeFrom<usize>`
    |
    = help: the trait `PartialOrd` is not implemented for `std::ops::RangeFrom<usize>`
-   = note: required by `std::cmp::PartialOrd::partial_cmp`
+note: required by `std::cmp::PartialOrd::partial_cmp`
+  --> $SRC_DIR/core/src/cmp.rs:LL:COL
+   |
+LL |     fn partial_cmp(&self, other: &Rhs) -> Option<Ordering>;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: this error originates in the derive macro `PartialOrd` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0277]: can't compare `std::ops::RangeFull` with `std::ops::RangeFull`
   --> $DIR/range_traits-1.rs:14:5
    |
+LL | #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
+   |                                ---------- in this derive macro expansion
+...
 LL |     d: RangeFull,
    |     ^^^^^^^^^^^^ no implementation for `std::ops::RangeFull < std::ops::RangeFull` and `std::ops::RangeFull > std::ops::RangeFull`
    |
    = help: the trait `PartialOrd` is not implemented for `std::ops::RangeFull`
-   = note: required by `std::cmp::PartialOrd::partial_cmp`
+note: required by `std::cmp::PartialOrd::partial_cmp`
+  --> $SRC_DIR/core/src/cmp.rs:LL:COL
+   |
+LL |     fn partial_cmp(&self, other: &Rhs) -> Option<Ordering>;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: this error originates in the derive macro `PartialOrd` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0277]: can't compare `std::ops::RangeInclusive<usize>` with `std::ops::RangeInclusive<usize>`
   --> $DIR/range_traits-1.rs:17:5
    |
+LL | #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
+   |                                ---------- in this derive macro expansion
+...
 LL |     e: RangeInclusive<usize>,
    |     ^^^^^^^^^^^^^^^^^^^^^^^^ no implementation for `std::ops::RangeInclusive<usize> < std::ops::RangeInclusive<usize>` and `std::ops::RangeInclusive<usize> > std::ops::RangeInclusive<usize>`
    |
    = help: the trait `PartialOrd` is not implemented for `std::ops::RangeInclusive<usize>`
-   = note: required by `std::cmp::PartialOrd::partial_cmp`
+note: required by `std::cmp::PartialOrd::partial_cmp`
+  --> $SRC_DIR/core/src/cmp.rs:LL:COL
+   |
+LL |     fn partial_cmp(&self, other: &Rhs) -> Option<Ordering>;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: this error originates in the derive macro `PartialOrd` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0277]: can't compare `std::ops::RangeToInclusive<usize>` with `std::ops::RangeToInclusive<usize>`
   --> $DIR/range_traits-1.rs:20:5
    |
+LL | #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
+   |                                ---------- in this derive macro expansion
+...
 LL |     f: RangeToInclusive<usize>,
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^ no implementation for `std::ops::RangeToInclusive<usize> < std::ops::RangeToInclusive<usize>` and `std::ops::RangeToInclusive<usize> > std::ops::RangeToInclusive<usize>`
    |
    = help: the trait `PartialOrd` is not implemented for `std::ops::RangeToInclusive<usize>`
-   = note: required by `std::cmp::PartialOrd::partial_cmp`
+note: required by `std::cmp::PartialOrd::partial_cmp`
+  --> $SRC_DIR/core/src/cmp.rs:LL:COL
+   |
+LL |     fn partial_cmp(&self, other: &Rhs) -> Option<Ordering>;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: this error originates in the derive macro `PartialOrd` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0277]: the trait bound `std::ops::Range<usize>: Ord` is not satisfied
   --> $DIR/range_traits-1.rs:5:5
    |
+LL | #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
+   |                                            --- in this derive macro expansion
+LL | struct AllTheRanges {
 LL |     a: Range<usize>,
    |     ^^^^^^^^^^^^^^^ the trait `Ord` is not implemented for `std::ops::Range<usize>`
    |
-   = note: required by `std::cmp::Ord::cmp`
+note: required by `std::cmp::Ord::cmp`
+  --> $SRC_DIR/core/src/cmp.rs:LL:COL
+   |
+LL |     fn cmp(&self, other: &Self) -> Ordering;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: this error originates in the derive macro `Ord` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0277]: the trait bound `std::ops::RangeTo<usize>: Ord` is not satisfied
   --> $DIR/range_traits-1.rs:8:5
    |
+LL | #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
+   |                                            --- in this derive macro expansion
+...
 LL |     b: RangeTo<usize>,
    |     ^^^^^^^^^^^^^^^^^ the trait `Ord` is not implemented for `std::ops::RangeTo<usize>`
    |
-   = note: required by `std::cmp::Ord::cmp`
+note: required by `std::cmp::Ord::cmp`
+  --> $SRC_DIR/core/src/cmp.rs:LL:COL
+   |
+LL |     fn cmp(&self, other: &Self) -> Ordering;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: this error originates in the derive macro `Ord` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0277]: the trait bound `std::ops::RangeFrom<usize>: Ord` is not satisfied
   --> $DIR/range_traits-1.rs:11:5
    |
+LL | #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
+   |                                            --- in this derive macro expansion
+...
 LL |     c: RangeFrom<usize>,
    |     ^^^^^^^^^^^^^^^^^^^ the trait `Ord` is not implemented for `std::ops::RangeFrom<usize>`
    |
-   = note: required by `std::cmp::Ord::cmp`
+note: required by `std::cmp::Ord::cmp`
+  --> $SRC_DIR/core/src/cmp.rs:LL:COL
+   |
+LL |     fn cmp(&self, other: &Self) -> Ordering;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: this error originates in the derive macro `Ord` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0277]: the trait bound `std::ops::RangeFull: Ord` is not satisfied
   --> $DIR/range_traits-1.rs:14:5
    |
+LL | #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
+   |                                            --- in this derive macro expansion
+...
 LL |     d: RangeFull,
    |     ^^^^^^^^^^^^ the trait `Ord` is not implemented for `std::ops::RangeFull`
    |
-   = note: required by `std::cmp::Ord::cmp`
+note: required by `std::cmp::Ord::cmp`
+  --> $SRC_DIR/core/src/cmp.rs:LL:COL
+   |
+LL |     fn cmp(&self, other: &Self) -> Ordering;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: this error originates in the derive macro `Ord` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0277]: the trait bound `std::ops::RangeInclusive<usize>: Ord` is not satisfied
   --> $DIR/range_traits-1.rs:17:5
    |
+LL | #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
+   |                                            --- in this derive macro expansion
+...
 LL |     e: RangeInclusive<usize>,
    |     ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Ord` is not implemented for `std::ops::RangeInclusive<usize>`
    |
-   = note: required by `std::cmp::Ord::cmp`
+note: required by `std::cmp::Ord::cmp`
+  --> $SRC_DIR/core/src/cmp.rs:LL:COL
+   |
+LL |     fn cmp(&self, other: &Self) -> Ordering;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: this error originates in the derive macro `Ord` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0277]: the trait bound `std::ops::RangeToInclusive<usize>: Ord` is not satisfied
   --> $DIR/range_traits-1.rs:20:5
    |
+LL | #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
+   |                                            --- in this derive macro expansion
+...
 LL |     f: RangeToInclusive<usize>,
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Ord` is not implemented for `std::ops::RangeToInclusive<usize>`
    |
-   = note: required by `std::cmp::Ord::cmp`
+note: required by `std::cmp::Ord::cmp`
+  --> $SRC_DIR/core/src/cmp.rs:LL:COL
+   |
+LL |     fn cmp(&self, other: &Self) -> Ordering;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: this error originates in the derive macro `Ord` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: aborting due to 12 previous errors
index 1949e762873761067502b20afd4462e50270cf29..e33253b19c4bdba4d396239783a1d85cf8be7a49 100644 (file)
@@ -1,6 +1,8 @@
 error[E0277]: `main` has invalid return type `Result<f32, ParseFloatError>`
   --> $DIR/termination-trait-test-wrong-type.rs:6:1
    |
+LL |   #[test]
+   |   ------- in this procedural macro expansion
 LL | / fn can_parse_zero_as_f32() -> Result<f32, ParseFloatError> {
 LL | |     "0".parse()
 LL | | }
index 6985f1b71a8db806b8aa7871e424a82029fd6634..4950b65414161afc230c7b6882523b6eb37b62d3 100644 (file)
@@ -502,7 +502,11 @@ LL |     if (let 0 = 0)? {}
    |        ^^^^^^^^^^^^ the `?` operator cannot be applied to type `bool`
    |
    = help: the trait `Try` is not implemented for `bool`
-   = note: required by `branch`
+note: required by `branch`
+  --> $SRC_DIR/core/src/ops/try_trait.rs:LL:COL
+   |
+LL |     fn branch(self) -> ControlFlow<Self::Residual, Self::Output>;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `FromResidual`)
   --> $DIR/disallowed-positions.rs:46:19
@@ -520,7 +524,11 @@ LL | | }
    | |_- this function should return `Result` or `Option` to accept `?`
    |
    = help: the trait `FromResidual<_>` is not implemented for `()`
-   = note: required by `from_residual`
+note: required by `from_residual`
+  --> $SRC_DIR/core/src/ops/try_trait.rs:LL:COL
+   |
+LL |     fn from_residual(residual: R) -> Self;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0308]: mismatched types
   --> $DIR/disallowed-positions.rs:56:8
@@ -660,7 +668,11 @@ LL |         if let 0 = 0? {}
    |                    ^^ the `?` operator cannot be applied to type `{integer}`
    |
    = help: the trait `Try` is not implemented for `{integer}`
-   = note: required by `branch`
+note: required by `branch`
+  --> $SRC_DIR/core/src/ops/try_trait.rs:LL:COL
+   |
+LL |     fn branch(self) -> ControlFlow<Self::Residual, Self::Output>;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0308]: mismatched types
   --> $DIR/disallowed-positions.rs:96:11
@@ -690,7 +702,11 @@ LL |     while (let 0 = 0)? {}
    |           ^^^^^^^^^^^^ the `?` operator cannot be applied to type `bool`
    |
    = help: the trait `Try` is not implemented for `bool`
-   = note: required by `branch`
+note: required by `branch`
+  --> $SRC_DIR/core/src/ops/try_trait.rs:LL:COL
+   |
+LL |     fn branch(self) -> ControlFlow<Self::Residual, Self::Output>;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `FromResidual`)
   --> $DIR/disallowed-positions.rs:110:22
@@ -708,7 +724,11 @@ LL | | }
    | |_- this function should return `Result` or `Option` to accept `?`
    |
    = help: the trait `FromResidual<_>` is not implemented for `()`
-   = note: required by `from_residual`
+note: required by `from_residual`
+  --> $SRC_DIR/core/src/ops/try_trait.rs:LL:COL
+   |
+LL |     fn from_residual(residual: R) -> Self;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0308]: mismatched types
   --> $DIR/disallowed-positions.rs:120:11
@@ -848,7 +868,11 @@ LL |         while let 0 = 0? {}
    |                       ^^ the `?` operator cannot be applied to type `{integer}`
    |
    = help: the trait `Try` is not implemented for `{integer}`
-   = note: required by `branch`
+note: required by `branch`
+  --> $SRC_DIR/core/src/ops/try_trait.rs:LL:COL
+   |
+LL |     fn branch(self) -> ControlFlow<Self::Residual, Self::Output>;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0614]: type `bool` cannot be dereferenced
   --> $DIR/disallowed-positions.rs:173:5
@@ -869,7 +893,11 @@ LL |     (let 0 = 0)?;
    |     ^^^^^^^^^^^^ the `?` operator cannot be applied to type `bool`
    |
    = help: the trait `Try` is not implemented for `bool`
-   = note: required by `branch`
+note: required by `branch`
+  --> $SRC_DIR/core/src/ops/try_trait.rs:LL:COL
+   |
+LL |     fn branch(self) -> ControlFlow<Self::Residual, Self::Output>;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `FromResidual`)
   --> $DIR/disallowed-positions.rs:183:16
@@ -887,7 +915,11 @@ LL | | }
    | |_- this function should return `Result` or `Option` to accept `?`
    |
    = help: the trait `FromResidual<_>` is not implemented for `()`
-   = note: required by `from_residual`
+note: required by `from_residual`
+  --> $SRC_DIR/core/src/ops/try_trait.rs:LL:COL
+   |
+LL |     fn from_residual(residual: R) -> Self;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0308]: mismatched types
   --> $DIR/disallowed-positions.rs:198:10
@@ -916,7 +948,11 @@ LL |         let 0 = 0?;
    |                 ^^ the `?` operator cannot be applied to type `{integer}`
    |
    = help: the trait `Try` is not implemented for `{integer}`
-   = note: required by `branch`
+note: required by `branch`
+  --> $SRC_DIR/core/src/ops/try_trait.rs:LL:COL
+   |
+LL |     fn branch(self) -> ControlFlow<Self::Residual, Self::Output>;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 104 previous errors; 2 warnings emitted
 
diff --git a/src/test/ui/rfc-2632-const-trait-impl/call-generic-in-impl.rs b/src/test/ui/rfc-2632-const-trait-impl/call-generic-in-impl.rs
new file mode 100644 (file)
index 0000000..536c1d7
--- /dev/null
@@ -0,0 +1,15 @@
+// check-pass
+#![feature(const_fn_trait_bound)]
+#![feature(const_trait_impl)]
+
+trait MyPartialEq {
+    fn eq(&self, other: &Self) -> bool;
+}
+
+impl<T: PartialEq> const MyPartialEq for T {
+    fn eq(&self, other: &Self) -> bool {
+        PartialEq::eq(self, other)
+    }
+}
+
+fn main() {}
index f2e556c63cbf3774bcfed5881f6b4114a0e844dd..a678731934f6e0e75a75cb6fc6bd453a54dadc3a 100644 (file)
@@ -9,7 +9,7 @@ LL |     async fn f(self: Pin<&Self>) -> impl Clone { self }
 help: to allow this `impl Trait` to capture borrowed data with lifetime `'1`, add `'_` as a bound
    |
 LL |     async fn f(self: Pin<&Self>) -> impl Clone + '_ { self }
-   |                                     ^^^^^^^^^^^^^^^
+   |                                                ^^^^
 
 error: aborting due to previous error
 
index 73766c31b93b60779f52797906257f384c9cd78c..962593e411e92a16aac8f7d1a3f35edaf77268ae 100644 (file)
@@ -9,7 +9,7 @@ LL |     fn f(self: Pin<&Self>) -> impl Clone { self }
 help: to allow this `impl Trait` to capture borrowed data with lifetime `'1`, add `'_` as a bound
    |
 LL |     fn f(self: Pin<&Self>) -> impl Clone + '_ { self }
-   |                               ^^^^^^^^^^^^^^^
+   |                                          ^^^^
 
 error: aborting due to previous error
 
index 1d3e33e4b05030c1d45698d4b76938fc8a1b972a..24dfdf8ebc2990b54b7c5f8ca861093b81cf0c4a 100644 (file)
@@ -1,11 +1,14 @@
 error[E0277]: the trait bound `u8: Tr` is not satisfied
   --> $DIR/issue-29595.rs:6:17
    |
-LL |     const C: Self;
-   |     -------------- required by `Tr::C`
-...
 LL |     let a: u8 = Tr::C;
    |                 ^^^^^ the trait `Tr` is not implemented for `u8`
+   |
+note: required by `Tr::C`
+  --> $DIR/issue-29595.rs:2:5
+   |
+LL |     const C: Self;
+   |     ^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
index 569608780def99ee4f066f3a31c38009dc97fa1d..4be1b22fc6b4f4d3b926a4a217f49e198f55a603 100644 (file)
@@ -1,6 +1,9 @@
 error[E0624]: associated function `new` is private
   --> $DIR/static-method-privacy.rs:9:19
    |
+LL |         fn new() -> S { S }
+   |         ------------- private associated function defined here
+...
 LL |     let _ = a::S::new();
    |                   ^^^ private associated function
 
index cea3d5d4df35d0a1a0d15c9fbcdc8e025dcda56b..e0a22c2df1aca529b65b67bcf33bf55ddf09b838 100644 (file)
@@ -1,11 +1,14 @@
 error[E0277]: the trait bound `NoClone: Clone` is not satisfied
   --> $DIR/struct-path-alias-bounds.rs:9:13
    |
-LL | struct S<T: Clone> { a: T }
-   | ------------------ required by `S`
-...
 LL |     let s = A { a: NoClone };
    |             ^ the trait `Clone` is not implemented for `NoClone`
+   |
+note: required by `S`
+  --> $DIR/struct-path-alias-bounds.rs:3:1
+   |
+LL | struct S<T: Clone> { a: T }
+   | ^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
index 3786457fb1ae3ac5fc54a2d2f83cd59ec9e5944f..d5d51324e63c5969594c0e9f163a565461dc1edb 100644 (file)
@@ -47,7 +47,11 @@ LL |     Pin::new(x)
    |     ^^^^^^^^ the trait `Unpin` is not implemented for `dyn Future<Output = i32> + Send`
    |
    = note: consider using `Box::pin`
-   = note: required by `Pin::<P>::new`
+note: required by `Pin::<P>::new`
+  --> $SRC_DIR/core/src/pin.rs:LL:COL
+   |
+LL |     pub const fn new(pointer: P) -> Pin<P> {
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: `dyn Future<Output = i32> + Send` cannot be unpinned
   --> $DIR/expected-boxed-future-isnt-pinned.rs:27:5
@@ -56,7 +60,11 @@ LL |     Pin::new(Box::new(x))
    |     ^^^^^^^^ the trait `Unpin` is not implemented for `dyn Future<Output = i32> + Send`
    |
    = note: consider using `Box::pin`
-   = note: required by `Pin::<P>::new`
+note: required by `Pin::<P>::new`
+  --> $SRC_DIR/core/src/pin.rs:LL:COL
+   |
+LL |     pub const fn new(pointer: P) -> Pin<P> {
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0308]: mismatched types
   --> $DIR/expected-boxed-future-isnt-pinned.rs:31:5
index eb67170d47cdf10c51e145be9582de38803b46d0..fcc49ef59d1294711d6e781e537976d074f83b66 100644 (file)
@@ -5,7 +5,11 @@ LL |     SadGirl {}.call()?;
    |     ^^^^^^^^^^^^^^^^^^ the `?` operator cannot be applied to type `impl Future`
    |
    = help: the trait `Try` is not implemented for `impl Future`
-   = note: required by `branch`
+note: required by `branch`
+  --> $SRC_DIR/core/src/ops/try_trait.rs:LL:COL
+   |
+LL |     fn branch(self) -> ControlFlow<Self::Residual, Self::Output>;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 help: consider `await`ing on the `Future`
    |
 LL |     SadGirl {}.call().await?;
index 49fa94da8592304a44ae8fbc25a62c1220b94067..649517b7d99da6c8cffb3d78e81e8ee8c836df19 100644 (file)
@@ -6,9 +6,12 @@ LL |     let o = Other::new(f);
    |                        |
    |                        expected an implementor of trait `SomeTrait`
    |                        help: consider borrowing here: `&f`
-...
+   |
+note: required by `Other::<'a, G>::new`
+  --> $DIR/issue-84973.rs:27:5
+   |
 LL |     pub fn new(g: G) -> Self {
-   |     ------------------------ required by `Other::<'a, G>::new`
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
index 2407d13714a2ad555938006713e07684149f71c7..05ba7808600b01131933898a9206009e9f8c3542 100644 (file)
@@ -9,7 +9,7 @@ LL |     fn iter(&self) -> impl Iterator<Item = Box<dyn Foo>> {
 help: to allow this `impl Trait` to capture borrowed data with lifetime `'1`, add `'_` as a bound
    |
 LL |     fn iter(&self) -> impl Iterator<Item = Box<dyn Foo>> + '_ {
-   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                                                          ^^^^
 
 error: lifetime may not live long enough
   --> $DIR/trait-object-nested-in-impl-trait.rs:39:9
@@ -47,7 +47,7 @@ LL |     fn iter<'a>(&'a self) -> impl Iterator<Item = Box<dyn Foo>> {
 help: to allow this `impl Trait` to capture borrowed data with lifetime `'a`, add `'a` as a bound
    |
 LL |     fn iter<'a>(&'a self) -> impl Iterator<Item = Box<dyn Foo>> + 'a {
-   |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                                                                 ^^^^
 
 error: aborting due to 4 previous errors
 
index 71b09d43612ea5915574615732dd6bc339c4b2b2..4d1b5306bb130120b748809e34ebdd1726fe326a 100644 (file)
@@ -5,7 +5,11 @@ LL |     let fp = BufWriter::new(fp);
    |                             ^^ the trait `std::io::Write` is not implemented for `&dyn std::io::Write`
    |
    = 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`
+note: required by `BufWriter::<W>::new`
+  --> $SRC_DIR/std/src/io/buffered/bufwriter.rs:LL:COL
+   |
+LL |     pub fn new(inner: W) -> BufWriter<W> {
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `&dyn std::io::Write: std::io::Write` is not satisfied
   --> $DIR/mut-borrow-needed-by-trait.rs:17:14
index 797406f869fe6b6b149b6e228a5352638ec64499..f332b7213d8bcc6e5b13b6721308bca4383af306 100644 (file)
@@ -1,8 +1,8 @@
 error[E0038]: the trait `Trait` cannot be made into an object
-  --> $DIR/object-unsafe-trait-references-self.rs:6:11
+  --> $DIR/object-unsafe-trait-references-self.rs:6:12
    |
 LL | fn bar(x: &dyn Trait) {}
-   |           ^^^^^^^^^^ `Trait` cannot be made into an object
+   |            ^^^^^^^^^ `Trait` cannot be made into an object
    |
    = help: consider moving `baz` to another trait
    = help: consider moving `bat` to another trait
@@ -17,10 +17,10 @@ LL |     fn bat(&self) -> Self {}
    |                      ^^^^ ...because method `bat` references the `Self` type in its return type
 
 error[E0038]: the trait `Other` cannot be made into an object
-  --> $DIR/object-unsafe-trait-references-self.rs:10:11
+  --> $DIR/object-unsafe-trait-references-self.rs:10:12
    |
 LL | fn foo(x: &dyn Other) {}
-   |           ^^^^^^^^^^ `Other` cannot be made into an object
+   |            ^^^^^^^^^ `Other` 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/object-unsafe-trait-references-self.rs:8:14
index a2caf846cc5febe6a3a4e7ea5650b39a9a54ae1d..4c18f6d79d077d679f92d2b1911c2a84555a0c38 100644 (file)
@@ -1,8 +1,8 @@
 error[E0038]: the trait `Trait` cannot be made into an object
-  --> $DIR/object-unsafe-trait-should-use-where-sized.rs:9:11
+  --> $DIR/object-unsafe-trait-should-use-where-sized.rs:9:12
    |
 LL | fn bar(x: &dyn Trait) {}
-   |           ^^^^^^^^^^ `Trait` cannot be made into an object
+   |            ^^^^^^^^^ `Trait` 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/object-unsafe-trait-should-use-where-sized.rs:5:8
index 9b8181647a0c15790715e665241946d0e47f7b5a..e68152d5fc3aa7006495013fd672e89567bf8ea9 100644 (file)
@@ -4,7 +4,11 @@ error[E0277]: the trait bound `&T: std::io::Read` is not satisfied
 LL |         let mut stream_reader = BufReader::new(&stream);
    |                                                ^^^^^^^ the trait `std::io::Read` is not implemented for `&T`
    |
-   = note: required by `BufReader::<R>::new`
+note: required by `BufReader::<R>::new`
+  --> $SRC_DIR/std/src/io/buffered/bufreader.rs:LL:COL
+   |
+LL |     pub fn new(inner: R) -> BufReader<R> {
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 help: consider removing the leading `&`-reference
    |
 LL |         let mut stream_reader = BufReader::new(stream);
index 4aa0ad219cf25fc1c26e03255af628b6f9fdb4c3..a5c01484d424c5e2829a6c3ceeeb543e66dfd895 100644 (file)
@@ -9,7 +9,11 @@ LL |     for (i, _) in &v.iter().enumerate() {
    |
    = help: the trait `Iterator` is not implemented for `&Enumerate<std::slice::Iter<'_, {integer}>>`
    = note: required because of the requirements on the impl of `IntoIterator` for `&Enumerate<std::slice::Iter<'_, {integer}>>`
-   = note: required by `into_iter`
+note: required by `into_iter`
+  --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
+   |
+LL |     fn into_iter(self) -> Self::IntoIter;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
index 15c4b7fcb8b3b089ba3950c18a06c84aec08b08d..b128590f9d0e75de0daaf3a1e082b814ae8bd85a 100644 (file)
@@ -9,7 +9,11 @@ LL |     for (i, _) in & & & & &v.iter().enumerate() {
    |
    = help: the trait `Iterator` is not implemented for `&&&&&Enumerate<std::slice::Iter<'_, {integer}>>`
    = note: required because of the requirements on the impl of `IntoIterator` for `&&&&&Enumerate<std::slice::Iter<'_, {integer}>>`
-   = note: required by `into_iter`
+note: required by `into_iter`
+  --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
+   |
+LL |     fn into_iter(self) -> Self::IntoIter;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
index 0bd6d956aff97196e00bb9d17151f98feeba0814..1c32a33e3712fb3a61e488ba175cfc8be7ae369d 100644 (file)
@@ -13,7 +13,11 @@ LL | |          .enumerate() {
    |
    = help: the trait `Iterator` is not implemented for `&&&&&Enumerate<std::slice::Iter<'_, {integer}>>`
    = note: required because of the requirements on the impl of `IntoIterator` for `&&&&&Enumerate<std::slice::Iter<'_, {integer}>>`
-   = note: required by `into_iter`
+note: required by `into_iter`
+  --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
+   |
+LL |     fn into_iter(self) -> Self::IntoIter;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
index 768893d6e25d475dc932f4a163f4abaff477230a..5a9d4286ce6d10fe715c6fed1ec337d139b48bf0 100644 (file)
@@ -29,7 +29,11 @@ LL |     let x: Vec<dyn Trait + Sized> = Vec::new();
    |                                     ^^^^^^^^ doesn't have a size known at compile-time
    |
    = help: the trait `Sized` is not implemented for `dyn Trait`
-   = note: required by `Vec::<T>::new`
+note: required by `Vec::<T>::new`
+  --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
+   |
+LL |     pub const fn new() -> Self {
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the size for values of type `dyn Trait` cannot be known at compilation time
   --> $DIR/bad-sized.rs:4:37
index 967b7320ab6cd9d4cc64009f465615d2a05efc38..7480d243f4e62fc3000c38c6c1694089583db0f2 100644 (file)
@@ -10,11 +10,14 @@ LL |     let baz: Foo<usize> = loop { };
 error[E0277]: the trait bound `{integer}: Trait` is not satisfied
   --> $DIR/on-structs-and-enums-locals.rs:10:15
    |
-LL | struct Foo<T:Trait> {
-   | ------------------- required by `Foo`
-...
 LL |     let foo = Foo {
    |               ^^^ the trait `Trait` is not implemented for `{integer}`
+   |
+note: required by `Foo`
+  --> $DIR/on-structs-and-enums-locals.rs:5:1
+   |
+LL | struct Foo<T:Trait> {
+   | ^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 2 previous errors
 
index 08f0f20e7480a688acf89032a9125723a976416b..ada2445c1c96259871914cd9f06756dbb9468f3a 100644 (file)
@@ -15,7 +15,11 @@ error[E0277]: the trait bound `{integer}: Trait` is not satisfied
 LL |     let foo = Foo {
    |               ^^^ the trait `Trait` is not implemented for `{integer}`
    |
-   = note: required by `Foo`
+note: required by `Foo`
+  --> $DIR/auxiliary/on_structs_and_enums_xc.rs:5:1
+   |
+LL | pub struct Foo<T:Trait> {
+   | ^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 2 previous errors
 
index 40386f706132bb6d38c8c01f6db040df4fd3c514..565899677bf1a74d55e7d39acf7d304edfcf2150 100644 (file)
@@ -1,9 +1,6 @@
 error[E0275]: overflow evaluating the requirement `SalsaStorage: RefUnwindSafe`
   --> $DIR/cycle-cache-err-60010.rs:69:5
    |
-LL |     fn parse(&self) {
-   |     --------------- required by `SourceDatabase::parse`
-...
 LL |     SourceDatabase::parse(db);
    |     ^^^^^^^^^^^^^^^^^^^^^
    |
@@ -25,6 +22,11 @@ note: required because of the requirements on the impl of `SourceDatabase` for `
    |
 LL | impl<T> SourceDatabase for T
    |         ^^^^^^^^^^^^^^     ^
+note: required by `SourceDatabase::parse`
+  --> $DIR/cycle-cache-err-60010.rs:14:5
+   |
+LL |     fn parse(&self) {
+   |     ^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
index bb11f18e54505bd8f953ae9599edbb2a8f405847..bc7b863ca4f5175392ef1a0451c994a5575e7e0e 100644 (file)
@@ -18,21 +18,26 @@ LL | fn with_trait<C:CompareToInts + CompareTo<i32>>(c: &C) -> bool {
 error[E0277]: the trait bound `dyn CompareToInts: CompareTo<i32>` is not satisfied
   --> $DIR/repeated-supertrait-ambig.rs:34:5
    |
-LL |     fn same_as(&self, t: T) -> bool;
-   |     -------------------------------- required by `CompareTo::same_as`
-...
 LL |     <dyn CompareToInts>::same_as(c, 22)
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `CompareTo<i32>` is not implemented for `dyn CompareToInts`
+   |
+note: required by `CompareTo::same_as`
+  --> $DIR/repeated-supertrait-ambig.rs:9:5
+   |
+LL |     fn same_as(&self, t: T) -> bool;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `C: CompareTo<i32>` is not satisfied
   --> $DIR/repeated-supertrait-ambig.rs:38:5
    |
-LL |     fn same_as(&self, t: T) -> bool;
-   |     -------------------------------- required by `CompareTo::same_as`
-...
 LL |     CompareTo::same_as(c, 22)
    |     ^^^^^^^^^^^^^^^^^^ the trait `CompareTo<i32>` is not implemented for `C`
    |
+note: required by `CompareTo::same_as`
+  --> $DIR/repeated-supertrait-ambig.rs:9:5
+   |
+LL |     fn same_as(&self, t: T) -> bool;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 help: consider further restricting this bound
    |
 LL | fn with_ufcs2<C:CompareToInts + CompareTo<i32>>(c: &C) -> bool {
index d1be955b41ed64fa2e50692adcb0ac09c7c1b713..23b78d023b600dc8f3665e3a5b6a6ea97eca3599 100644 (file)
@@ -1,11 +1,18 @@
 error[E0277]: the trait bound `Foo: Clone` is not satisfied
   --> $DIR/issue-71136.rs:5:5
    |
+LL | #[derive(Clone)]
+   |          ----- in this derive macro expansion
+LL | struct FooHolster {
 LL |     the_foos: Vec<Foo>,
    |     ^^^^^^^^^^^^^^^^^^ expected an implementor of trait `Clone`
    |
    = note: required because of the requirements on the impl of `Clone` for `Vec<Foo>`
-   = note: required by `clone`
+note: required by `clone`
+  --> $SRC_DIR/core/src/clone.rs:LL:COL
+   |
+LL |     fn clone(&self) -> Self;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^
    = note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: aborting due to previous error
index d788f1871ffac83233b8cd186a5706baeb621bac..68347207bda45d10b0a6e046e513b6848c5fa979 100644 (file)
@@ -17,7 +17,11 @@ LL |     let ips: Vec<_> = (0..100_000).map(|_| u32::from(0u32.into())).collect(
    |                                            cannot infer type for type parameter `T` declared on the trait `From`
    |
    = note: cannot satisfy `u32: From<_>`
-   = note: required by `from`
+note: required by `from`
+  --> $SRC_DIR/core/src/convert/mod.rs:LL:COL
+   |
+LL |     fn from(_: T) -> Self;
+   |     ^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0283]: type annotations needed for `Box<T>`
   --> $DIR/issue-77982.rs:35:16
index 7e990cdc34e25fbda74db60ceb4aa8ffe21bd22e..2f5b4ad0e62c88069a285bf3bbade8d8e36fc3f4 100644 (file)
@@ -1,13 +1,20 @@
 error[E0277]: the trait bound `&mut T: Clone` is not satisfied
   --> $DIR/issue-79458.rs:6:5
    |
+LL | #[derive(Clone)]
+   |          ----- in this derive macro expansion
+LL | struct Foo<'a, T> {
 LL |     bar: &'a mut T
    |     ^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `&mut T`
    |
    = help: the following implementations were found:
              <&T as Clone>
    = note: `Clone` is implemented for `&T`, but not for `&mut T`
-   = note: required by `clone`
+note: required by `clone`
+  --> $SRC_DIR/core/src/clone.rs:LL:COL
+   |
+LL |     fn clone(&self) -> Self;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^
    = note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: aborting due to previous error
index 30daf8e27702441b0504987446bc7d6c30d70a38..2260dcfc70ea38f4d4eff58a6ca91234fba9d67a 100644 (file)
@@ -35,6 +35,9 @@ LL | use method::B;
 error[E0624]: associated function `a` is private
   --> $DIR/item-privacy.rs:72:7
    |
+LL |         fn a(&self) { }
+   |         ----------- private associated function defined here
+...
 LL |     c.a();
    |       ^ private associated function
 
@@ -72,6 +75,9 @@ LL | use method::B;
 error[E0624]: associated function `a` is private
   --> $DIR/item-privacy.rs:84:14
    |
+LL |         fn a(&self) { }
+   |         ----------- private associated function defined here
+...
 LL |     <dyn C>::a(&S);
    |              ^ private associated function
 
@@ -109,6 +115,9 @@ LL | use assoc_const::B;
 error[E0624]: associated constant `A` is private
   --> $DIR/item-privacy.rs:101:14
    |
+LL |         const A: u8 = 0;
+   |         ---------------- private associated constant defined here
+...
 LL |     <dyn C>::A;
    |              ^ private associated constant
 
index 99f330b38ae3de6e37660b84bd525e0fcc731973..8e991ec018c3e0c105bb4ff32074f132747b3d9d 100644 (file)
@@ -1,6 +1,9 @@
 error[E0624]: associated function `method` is private
   --> $DIR/method-private.rs:19:9
    |
+LL |         fn method(&self) {}
+   |         ---------------- private associated function defined here
+...
 LL |     foo.method();
    |         ^^^^^^ private associated function
    |
index 4f7d1be793891c4526b2c292f34b0c7266c6de09..cad298cf247330c7b075701557f1b254010f6698 100644 (file)
@@ -1,13 +1,15 @@
 error[E0277]: `dummy::TestType` cannot be sent between threads safely
   --> $DIR/negated-auto-traits-error.rs:23:11
    |
-LL | struct Outer<T: Send>(T);
-   | ------------------------- required by `Outer`
-...
 LL |     Outer(TestType);
    |           ^^^^^^^^ `dummy::TestType` cannot be sent between threads safely
    |
    = help: the trait `Send` is not implemented for `dummy::TestType`
+note: required by `Outer`
+  --> $DIR/negated-auto-traits-error.rs:10:1
+   |
+LL | struct Outer<T: Send>(T);
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: `dummy::TestType` cannot be sent between threads safely
   --> $DIR/negated-auto-traits-error.rs:23:5
index fb4a443435fa5d5aca98fbac1d4cfd32e5dc4cb8..526c0e9ed540fa3485fbe1d8726246bdc19f87d8 100644 (file)
@@ -1,14 +1,16 @@
 error[E0277]: the trait bound `(): MyTrait` is not satisfied
   --> $DIR/no-use.rs:10:26
    |
-LL | trait MyTrait { fn foo(&self); }
-   |                 -------------- required by `MyTrait::foo`
-...
 LL |     <() as MyTrait>::foo(&());
    |                          ^^^ the trait `MyTrait` is not implemented for `()`
    |
    = help: the following implementations were found:
              <() as MyTrait>
+note: required by `MyTrait::foo`
+  --> $DIR/no-use.rs:5:17
+   |
+LL | trait MyTrait { fn foo(&self); }
+   |                 ^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
index 2b9ce7321eeae19100bb97b253f379d98fd97c5c..c8c804a9013bfd80f3f4008156e4af9b95252c2b 100644 (file)
@@ -1,13 +1,15 @@
 error[E0283]: type annotations needed
   --> $DIR/static-method-generic-inference.rs:24:25
    |
-LL |         fn new() -> T;
-   |         -------------- required by `HasNew::new`
-...
 LL |     let _f: base::Foo = base::HasNew::new();
    |                         ^^^^^^^^^^^^^^^^^ cannot infer type
    |
    = note: cannot satisfy `_: HasNew<Foo>`
+note: required by `HasNew::new`
+  --> $DIR/static-method-generic-inference.rs:8:9
+   |
+LL |         fn new() -> T;
+   |         ^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
index 025706480821d29d2d23ebec267dae624bfd4941..f15e7e35839d584f8f37804ba6c7dd744a4217a4 100644 (file)
@@ -38,7 +38,11 @@ error[E0277]: the trait bound `u64: From<T>` is not satisfied
 LL |     <u64 as From<T>>::from;
    |     ^^^^^^^^^^^^^^^^^^^^^^ the trait `From<T>` is not implemented for `u64`
    |
-   = note: required by `from`
+note: required by `from`
+  --> $SRC_DIR/core/src/convert/mod.rs:LL:COL
+   |
+LL |     fn from(_: T) -> Self;
+   |     ^^^^^^^^^^^^^^^^^^^^^^
 help: consider introducing a `where` bound, but there might be an alternative better way to express this requirement
    |
 LL | fn check<T: Iterator, U: ?Sized>() where u64: From<T> {
@@ -50,7 +54,11 @@ error[E0277]: the trait bound `u64: From<<T as Iterator>::Item>` is not satisfie
 LL |     <u64 as From<<T as Iterator>::Item>>::from;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `From<<T as Iterator>::Item>` is not implemented for `u64`
    |
-   = note: required by `from`
+note: required by `from`
+  --> $SRC_DIR/core/src/convert/mod.rs:LL:COL
+   |
+LL |     fn from(_: T) -> Self;
+   |     ^^^^^^^^^^^^^^^^^^^^^^
 help: consider introducing a `where` bound, but there might be an alternative better way to express this requirement
    |
 LL | fn check<T: Iterator, U: ?Sized>() where u64: From<<T as Iterator>::Item> {
@@ -62,7 +70,11 @@ error[E0277]: the trait bound `Misc<_>: From<T>` is not satisfied
 LL |     <Misc<_> as From<T>>::from;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `From<T>` is not implemented for `Misc<_>`
    |
-   = note: required by `from`
+note: required by `from`
+  --> $SRC_DIR/core/src/convert/mod.rs:LL:COL
+   |
+LL |     fn from(_: T) -> Self;
+   |     ^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the size for values of type `[T]` cannot be known at compilation time
   --> $DIR/suggest-where-clause.rs:28:20
index de7a431d6ff541db718d3805433f37e5dff112a3..41a19bff8703b21571f1294198490fb422582903 100644 (file)
@@ -23,11 +23,14 @@ LL | pub trait Foo {
 error[E0277]: the trait bound `i32: Foo` is not satisfied
   --> $DIR/trivial-bounds-leak.rs:25:15
    |
-LL |     fn test(&self);
-   |     --------------- required by `Foo::test`
-...
 LL |     Foo::test(&4i32);
    |               ^^^^^ the trait `Foo` is not implemented for `i32`
+   |
+note: required by `Foo::test`
+  --> $DIR/trivial-bounds-leak.rs:5:5
+   |
+LL |     fn test(&self);
+   |     ^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `i32: Foo` is not satisfied
   --> $DIR/trivial-bounds-leak.rs:26:22
index ec5e91f10c28614bb3cef54ee7064d200d1ec4e2..fce8dbab4856ca7daf4e4de7278e22f62cb8b29c 100644 (file)
@@ -8,7 +8,11 @@ LL |         Err("")?;
    = help: the following implementations were found:
              <TryFromSliceError as From<Infallible>>
    = note: required because of the requirements on the impl of `FromResidual<Result<Infallible, &str>>` for `Result<u32, TryFromSliceError>`
-   = note: required by `from_residual`
+note: required by `from_residual`
+  --> $SRC_DIR/core/src/ops/try_trait.rs:LL:COL
+   |
+LL |     fn from_residual(residual: R) -> Self;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0271]: type mismatch resolving `<Result<i32, i32> as Try>::Output == &str`
   --> $DIR/try-block-bad-type.rs:12:9
@@ -29,7 +33,11 @@ LL |     let res: () = try { };
    |                         ^ could not wrap the final value of the block as `()` doesn't implement `Try`
    |
    = help: the trait `Try` is not implemented for `()`
-   = note: required by `from_output`
+note: required by `from_output`
+  --> $SRC_DIR/core/src/ops/try_trait.rs:LL:COL
+   |
+LL |     fn from_output(output: Self::Output) -> Self;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: a `try` block must return `Result` or `Option` (or another type that implements `Try`)
   --> $DIR/try-block-bad-type.rs:20:26
@@ -38,7 +46,11 @@ LL |     let res: i32 = try { 5 };
    |                          ^ could not wrap the final value of the block as `i32` doesn't implement `Try`
    |
    = help: the trait `Try` is not implemented for `i32`
-   = note: required by `from_output`
+note: required by `from_output`
+  --> $SRC_DIR/core/src/ops/try_trait.rs:LL:COL
+   |
+LL |     fn from_output(output: Self::Output) -> Self;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 5 previous errors
 
index c83351d5c434634766476d45340a5b533cb38494..4270df5b4063cc05439155017a371c7974f9e532 100644 (file)
@@ -5,7 +5,11 @@ LL |     while try { false } {}
    |                 ^^^^^ could not wrap the final value of the block as `bool` doesn't implement `Try`
    |
    = help: the trait `Try` is not implemented for `bool`
-   = note: required by `from_output`
+note: required by `from_output`
+  --> $SRC_DIR/core/src/ops/try_trait.rs:LL:COL
+   |
+LL |     fn from_output(output: Self::Output) -> Self;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
index f5b315c25193377cf0987c90ff30a65e92e41be1..5cecf9128bb2ca4118878aa27914d6116f7b8fc0 100644 (file)
@@ -11,7 +11,11 @@ LL |     Ok(Err(123_i32)?)
              <u8 as From<NonZeroU8>>
              <u8 as From<bool>>
    = note: required because of the requirements on the impl of `FromResidual<Result<Infallible, i32>>` for `Result<u64, u8>`
-   = note: required by `from_residual`
+note: required by `from_residual`
+  --> $SRC_DIR/core/src/ops/try_trait.rs:LL:COL
+   |
+LL |     fn from_residual(residual: R) -> Self;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the `?` operator can only be used on `Result`s, not `Option`s, in a function that returns `Result`
   --> $DIR/bad-interconversion.rs:11:12
@@ -25,7 +29,11 @@ LL | | }
    | |_- this function returns a `Result`
    |
    = help: the trait `FromResidual<Option<Infallible>>` is not implemented for `Result<u64, String>`
-   = note: required by `from_residual`
+note: required by `from_residual`
+  --> $SRC_DIR/core/src/ops/try_trait.rs:LL:COL
+   |
+LL |     fn from_residual(residual: R) -> Self;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the `?` operator can only be used on `Result`s in a function that returns `Result`
   --> $DIR/bad-interconversion.rs:17:31
@@ -38,7 +46,11 @@ LL | | }
    | |_- this function returns a `Result`
    |
    = help: the trait `FromResidual<ControlFlow<{integer}, Infallible>>` is not implemented for `Result<u64, String>`
-   = note: required by `from_residual`
+note: required by `from_residual`
+  --> $SRC_DIR/core/src/ops/try_trait.rs:LL:COL
+   |
+LL |     fn from_residual(residual: R) -> Self;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the `?` operator can only be used on `Option`s, not `Result`s, in a function that returns `Option`
   --> $DIR/bad-interconversion.rs:22:22
@@ -51,7 +63,11 @@ LL | | }
    | |_- this function returns an `Option`
    |
    = help: the trait `FromResidual<Result<Infallible, &str>>` is not implemented for `Option<u16>`
-   = note: required by `from_residual`
+note: required by `from_residual`
+  --> $SRC_DIR/core/src/ops/try_trait.rs:LL:COL
+   |
+LL |     fn from_residual(residual: R) -> Self;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the `?` operator can only be used on `Option`s in a function that returns `Option`
   --> $DIR/bad-interconversion.rs:27:33
@@ -64,7 +80,11 @@ LL | | }
    | |_- this function returns an `Option`
    |
    = help: the trait `FromResidual<ControlFlow<{integer}, Infallible>>` is not implemented for `Option<u64>`
-   = note: required by `from_residual`
+note: required by `from_residual`
+  --> $SRC_DIR/core/src/ops/try_trait.rs:LL:COL
+   |
+LL |     fn from_residual(residual: R) -> Self;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the `?` operator can only be used on `ControlFlow`s in a function that returns `ControlFlow`
   --> $DIR/bad-interconversion.rs:32:39
@@ -77,7 +97,11 @@ LL | | }
    | |_- this function returns a `ControlFlow`
    |
    = help: the trait `FromResidual<Result<Infallible, &str>>` is not implemented for `ControlFlow<String>`
-   = note: required by `from_residual`
+note: required by `from_residual`
+  --> $SRC_DIR/core/src/ops/try_trait.rs:LL:COL
+   |
+LL |     fn from_residual(residual: R) -> Self;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the `?` operator can only be used on `ControlFlow`s in a function that returns `ControlFlow`
   --> $DIR/bad-interconversion.rs:37:12
@@ -91,7 +115,11 @@ LL | | }
    | |_- this function returns a `ControlFlow`
    |
    = help: the trait `FromResidual<Option<Infallible>>` is not implemented for `ControlFlow<u64>`
-   = note: required by `from_residual`
+note: required by `from_residual`
+  --> $SRC_DIR/core/src/ops/try_trait.rs:LL:COL
+   |
+LL |     fn from_residual(residual: R) -> Self;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the `?` operator in a function that returns `ControlFlow<B, _>` can only be used on other `ControlFlow<B, _>`s (with the same Break type)
   --> $DIR/bad-interconversion.rs:43:29
@@ -106,7 +134,11 @@ LL | | }
    |
    = help: the trait `FromResidual<ControlFlow<u8, Infallible>>` is not implemented for `ControlFlow<i64>`
    = note: unlike `Result`, there's no `From`-conversion performed for `ControlFlow`
-   = note: required by `from_residual`
+note: required by `from_residual`
+  --> $SRC_DIR/core/src/ops/try_trait.rs:LL:COL
+   |
+LL |     fn from_residual(residual: R) -> Self;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 8 previous errors
 
index 9f7d80d4f23cdc1bdb834e1b023d98f591bc9d2b..f89813e729fad60c22e2f8da16b3aec924137136 100644 (file)
@@ -10,7 +10,11 @@ LL | | }
    | |_- this function returns a `Result`
    |
    = help: the trait `FromResidual<Option<Infallible>>` is not implemented for `Result<(), ()>`
-   = note: required by `from_residual`
+note: required by `from_residual`
+  --> $SRC_DIR/core/src/ops/try_trait.rs:LL:COL
+   |
+LL |     fn from_residual(residual: R) -> Self;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the `?` operator can only be used on `Option`s, not `Result`s, in a function that returns `Option`
   --> $DIR/option-to-result.rs:11:6
@@ -24,7 +28,11 @@ LL | | }
    | |_- this function returns an `Option`
    |
    = help: the trait `FromResidual<Result<Infallible, i32>>` is not implemented for `Option<i32>`
-   = note: required by `from_residual`
+note: required by `from_residual`
+  --> $SRC_DIR/core/src/ops/try_trait.rs:LL:COL
+   |
+LL |     fn from_residual(residual: R) -> Self;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 2 previous errors
 
index e7c67c21bb3e3f1e9155733303f7fd28ec51b687..bb65aae561f97949a5277c0435073d3e340ce7fc 100644 (file)
@@ -10,7 +10,11 @@ LL | | }
    | |_- this function should return `Result` or `Option` to accept `?`
    |
    = help: the trait `FromResidual<Option<Infallible>>` is not implemented for `u32`
-   = note: required by `from_residual`
+note: required by `from_residual`
+  --> $SRC_DIR/core/src/ops/try_trait.rs:LL:COL
+   |
+LL |     fn from_residual(residual: R) -> Self;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the `?` operator can only be used in a closure that returns `Result` or `Option` (or another type that implements `FromResidual`)
   --> $DIR/try-on-option-diagnostics.rs:14:10
@@ -25,7 +29,11 @@ LL | |     };
    | |_____- this function should return `Result` or `Option` to accept `?`
    |
    = help: the trait `FromResidual<Option<Infallible>>` is not implemented for `{integer}`
-   = note: required by `from_residual`
+note: required by `from_residual`
+  --> $SRC_DIR/core/src/ops/try_trait.rs:LL:COL
+   |
+LL |     fn from_residual(residual: R) -> Self;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the `?` operator can only be used in a method that returns `Result` or `Option` (or another type that implements `FromResidual`)
   --> $DIR/try-on-option-diagnostics.rs:26:14
@@ -38,7 +46,11 @@ LL | |         }
    | |_________- this function should return `Result` or `Option` to accept `?`
    |
    = help: the trait `FromResidual<Option<Infallible>>` is not implemented for `()`
-   = note: required by `from_residual`
+note: required by `from_residual`
+  --> $SRC_DIR/core/src/ops/try_trait.rs:LL:COL
+   |
+LL |     fn from_residual(residual: R) -> Self;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the `?` operator can only be used in a trait method that returns `Result` or `Option` (or another type that implements `FromResidual`)
   --> $DIR/try-on-option-diagnostics.rs:39:14
@@ -51,7 +63,11 @@ LL | |         }
    | |_________- this function should return `Result` or `Option` to accept `?`
    |
    = help: the trait `FromResidual<Option<Infallible>>` is not implemented for `()`
-   = note: required by `from_residual`
+note: required by `from_residual`
+  --> $SRC_DIR/core/src/ops/try_trait.rs:LL:COL
+   |
+LL |     fn from_residual(residual: R) -> Self;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 4 previous errors
 
index 604baa8550b45837b07679775fd87f4b24040ea5..b522dd5709b2946601927dc00480e362887fd5c2 100644 (file)
@@ -10,7 +10,11 @@ LL | | }
    | |_- this function returns a `Result`
    |
    = help: the trait `FromResidual<Option<Infallible>>` is not implemented for `Result<u32, ()>`
-   = note: required by `from_residual`
+note: required by `from_residual`
+  --> $SRC_DIR/core/src/ops/try_trait.rs:LL:COL
+   |
+LL |     fn from_residual(residual: R) -> Self;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `FromResidual`)
   --> $DIR/try-on-option.rs:13:6
@@ -24,7 +28,11 @@ LL | | }
    | |_- this function should return `Result` or `Option` to accept `?`
    |
    = help: the trait `FromResidual<Option<Infallible>>` is not implemented for `u32`
-   = note: required by `from_residual`
+note: required by `from_residual`
+  --> $SRC_DIR/core/src/ops/try_trait.rs:LL:COL
+   |
+LL |     fn from_residual(residual: R) -> Self;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 2 previous errors
 
index 7d42c2e4d10d367cdb4938a7493740ff74f039df..dd893cadff77a2e85d9ab0628af77982c7c4c538 100644 (file)
@@ -12,7 +12,11 @@ LL | | }
    | |_- this function should return `Result` or `Option` to accept `?`
    |
    = help: the trait `FromResidual<Result<Infallible, std::io::Error>>` is not implemented for `()`
-   = note: required by `from_residual`
+note: required by `from_residual`
+  --> $SRC_DIR/core/src/ops/try_trait.rs:LL:COL
+   |
+LL |     fn from_residual(residual: R) -> Self;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the `?` operator can only be applied to values that implement `Try`
   --> $DIR/try-operator-on-main.rs:10:5
@@ -21,7 +25,11 @@ LL |     ()?;
    |     ^^^ the `?` operator cannot be applied to type `()`
    |
    = help: the trait `Try` is not implemented for `()`
-   = note: required by `branch`
+note: required by `branch`
+  --> $SRC_DIR/core/src/ops/try_trait.rs:LL:COL
+   |
+LL |     fn branch(self) -> ControlFlow<Self::Residual, Self::Output>;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `FromResidual`)
   --> $DIR/try-operator-on-main.rs:10:7
@@ -39,7 +47,11 @@ LL | | }
    | |_- this function should return `Result` or `Option` to accept `?`
    |
    = help: the trait `FromResidual<_>` is not implemented for `()`
-   = note: required by `from_residual`
+note: required by `from_residual`
+  --> $SRC_DIR/core/src/ops/try_trait.rs:LL:COL
+   |
+LL |     fn from_residual(residual: R) -> Self;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `(): Try` is not satisfied
   --> $DIR/try-operator-on-main.rs:14:25
@@ -57,7 +69,11 @@ LL |     ()?;
    |     ^^^ the `?` operator cannot be applied to type `()`
    |
    = help: the trait `Try` is not implemented for `()`
-   = note: required by `branch`
+note: required by `branch`
+  --> $SRC_DIR/core/src/ops/try_trait.rs:LL:COL
+   |
+LL |     fn branch(self) -> ControlFlow<Self::Residual, Self::Output>;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 5 previous errors
 
index 1a03ce79661115b2e44b91f0587e816b4171cb90..a8dd6a93d3dbfd5a34887e76d4bf96c1c0fd8715 100644 (file)
@@ -1,18 +1,10 @@
-warning: the feature `impl_trait_in_bindings` is incomplete and may not be safe to use and/or cause compiler crashes
+warning: the feature `type_alias_impl_trait` is incomplete and may not be safe to use and/or cause compiler crashes
   --> $DIR/issue-53096.rs:4:32
    |
-LL | #![cfg_attr(full_tait, feature(impl_trait_in_bindings, type_alias_impl_trait))]
-   |                                ^^^^^^^^^^^^^^^^^^^^^^
+LL | #![cfg_attr(full_tait, feature(type_alias_impl_trait))]
+   |                                ^^^^^^^^^^^^^^^^^^^^^
    |
    = note: `#[warn(incomplete_features)]` on by default
-   = note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
-
-warning: the feature `type_alias_impl_trait` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/issue-53096.rs:4:56
-   |
-LL | #![cfg_attr(full_tait, feature(impl_trait_in_bindings, type_alias_impl_trait))]
-   |                                                        ^^^^^^^^^^^^^^^^^^^^^
-   |
    = note: see issue #63063 <https://github.com/rust-lang/rust/issues/63063> for more information
 
 error: fatal error triggered by #[rustc_error]
@@ -21,5 +13,5 @@ error: fatal error triggered by #[rustc_error]
 LL | fn main() {}
    | ^^^^^^^^^
 
-error: aborting due to previous error; 2 warnings emitted
+error: aborting due to previous error; 1 warning emitted
 
index c6c7a51618dd3ad405220bb58783f384f514f9d8..4210d0c1cb17a460b703bea2e368bb75849e999b 100644 (file)
@@ -1,12 +1,8 @@
-error[E0658]: type alias impl trait is not permitted here
-  --> $DIR/issue-53096.rs:10:19
+error: fatal error triggered by #[rustc_error]
+  --> $DIR/issue-53096.rs:14:1
    |
-LL | const BAZR: Foo = bar();
-   |                   ^^^^^
-   |
-   = note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
-   = help: add `#![feature(impl_trait_in_bindings)]` to the crate attributes to enable
+LL | fn main() {}
+   | ^^^^^^^^^
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0658`.
index fb621dc0bce9fecfdcba88c9e0edef58f89cad0b..7bb0066b7ef4209ad9202b29490d8c0e66c63391 100644 (file)
@@ -1,14 +1,14 @@
 #![feature(const_impl_trait, const_fn_fn_ptr_basics, rustc_attrs)]
 // revisions: min_tait full_tait
 #![feature(min_type_alias_impl_trait)]
-#![cfg_attr(full_tait, feature(impl_trait_in_bindings, type_alias_impl_trait))]
+#![cfg_attr(full_tait, feature(type_alias_impl_trait))]
 //[full_tait]~^ WARN incomplete
-//[full_tait]~| WARN incomplete
 
 type Foo = impl Fn() -> usize;
-const fn bar() -> Foo { || 0usize }
+const fn bar() -> Foo {
+    || 0usize
+}
 const BAZR: Foo = bar();
-//[min_tait]~^ ERROR not permitted here
 
 #[rustc_error]
-fn main() {} //[full_tait]~ ERROR
+fn main() {} //~ ERROR
index 70d049ffa76bdb367fb8272f8f2dffcf71c67621..b23fed5dadfe77e1eabe97dcdd05deed81d22ba6 100644 (file)
@@ -1,25 +1,17 @@
-warning: the feature `impl_trait_in_bindings` is incomplete and may not be safe to use and/or cause compiler crashes
+warning: the feature `type_alias_impl_trait` is incomplete and may not be safe to use and/or cause compiler crashes
   --> $DIR/issue-53678-generator-and-const-fn.rs:4:32
    |
-LL | #![cfg_attr(full_tait, feature(impl_trait_in_bindings, type_alias_impl_trait))]
-   |                                ^^^^^^^^^^^^^^^^^^^^^^
+LL | #![cfg_attr(full_tait, feature(type_alias_impl_trait))]
+   |                                ^^^^^^^^^^^^^^^^^^^^^
    |
    = note: `#[warn(incomplete_features)]` on by default
-   = note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
-
-warning: the feature `type_alias_impl_trait` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/issue-53678-generator-and-const-fn.rs:4:56
-   |
-LL | #![cfg_attr(full_tait, feature(impl_trait_in_bindings, type_alias_impl_trait))]
-   |                                                        ^^^^^^^^^^^^^^^^^^^^^
-   |
    = note: see issue #63063 <https://github.com/rust-lang/rust/issues/63063> for more information
 
 error: fatal error triggered by #[rustc_error]
-  --> $DIR/issue-53678-generator-and-const-fn.rs:23:1
+  --> $DIR/issue-53678-generator-and-const-fn.rs:22:1
    |
 LL | fn main() {}
    | ^^^^^^^^^
 
-error: aborting due to previous error; 2 warnings emitted
+error: aborting due to previous error; 1 warning emitted
 
index a3dea45a6a5ad6901fe72c20428147190e5c3c0b..fabba2183531f9c81d5fd1ecfd3d04782b886e98 100644 (file)
@@ -1,12 +1,8 @@
-error[E0658]: type alias impl trait is not permitted here
-  --> $DIR/issue-53678-generator-and-const-fn.rs:20:36
+error: fatal error triggered by #[rustc_error]
+  --> $DIR/issue-53678-generator-and-const-fn.rs:22:1
    |
-LL | const FOO: GenOnce<usize, usize> = const_generator(10, 100);
-   |                                    ^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
-   = help: add `#![feature(impl_trait_in_bindings)]` to the crate attributes to enable
+LL | fn main() {}
+   | ^^^^^^^^^
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0658`.
index bf607d29ce46241ea6b833dfb317d5cce2b9b39a..a8215c41826f8f0d4c89a35c503e1b3b0b7ef1b5 100644 (file)
@@ -1,9 +1,8 @@
 #![feature(const_impl_trait, generators, generator_trait, rustc_attrs)]
 // revisions: min_tait full_tait
 #![feature(min_type_alias_impl_trait)]
-#![cfg_attr(full_tait, feature(impl_trait_in_bindings, type_alias_impl_trait))]
+#![cfg_attr(full_tait, feature(type_alias_impl_trait))]
 //[full_tait]~^ WARN incomplete
-//[full_tait]~| WARN incomplete
 
 use std::ops::Generator;
 
@@ -17,7 +16,7 @@ const fn const_generator<Y, R>(yielding: Y, returning: R) -> GenOnce<Y, R> {
     }
 }
 
-const FOO: GenOnce<usize, usize> = const_generator(10, 100); //[min_tait]~ ERROR not permitted here
+const FOO: GenOnce<usize, usize> = const_generator(10, 100);
 
 #[rustc_error]
-fn main() {} //[full_tait]~ ERROR
+fn main() {} //~ ERROR
index 6857d5264b65ed717bc5bdf1410d3941fe57588d..4906ea9c2e261a6c0d58560992398052c880c7b0 100644 (file)
@@ -8,13 +8,13 @@ LL |     type Item = impl Bug;
    = help: add `#![feature(min_type_alias_impl_trait)]` to the crate attributes to enable
 
 error[E0658]: type alias impl trait is not permitted here
-  --> $DIR/issue-60371.rs:14:37
+  --> $DIR/issue-60371.rs:14:40
    |
 LL |     const FUN: fn() -> Self::Item = || ();
-   |                                     ^^^^^
+   |                                        ^
    |
-   = note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
-   = help: add `#![feature(impl_trait_in_bindings)]` to the crate attributes to enable
+   = note: see issue #63063 <https://github.com/rust-lang/rust/issues/63063> for more information
+   = help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable
 
 error[E0277]: the trait bound `(): Bug` is not satisfied
   --> $DIR/issue-60371.rs:10:17
index 5edf73c8cedc645a069f7d1522a6809e8133882b..9d3f366ad810a34b431a2c0d56c22e64ed461d1f 100644 (file)
@@ -1,25 +1,17 @@
 warning: the feature `type_alias_impl_trait` is incomplete and may not be safe to use and/or cause compiler crashes
   --> $DIR/issue-60407.rs:3:32
    |
-LL | #![cfg_attr(full_tait, feature(type_alias_impl_trait, impl_trait_in_bindings))]
+LL | #![cfg_attr(full_tait, feature(type_alias_impl_trait))]
    |                                ^^^^^^^^^^^^^^^^^^^^^
    |
    = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #63063 <https://github.com/rust-lang/rust/issues/63063> for more information
 
-warning: the feature `impl_trait_in_bindings` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/issue-60407.rs:3:55
-   |
-LL | #![cfg_attr(full_tait, feature(type_alias_impl_trait, impl_trait_in_bindings))]
-   |                                                       ^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
-
 error: fatal error triggered by #[rustc_error]
-  --> $DIR/issue-60407.rs:12:1
+  --> $DIR/issue-60407.rs:11:1
    |
 LL | fn main() {
    | ^^^^^^^^^
 
-error: aborting due to previous error; 2 warnings emitted
+error: aborting due to previous error; 1 warning emitted
 
index edb8141c1b1042de460106431d0a82dccb6bb04a..1a3ceafa3e29405bf287ff3c19184db6ad45e115 100644 (file)
@@ -1,24 +1,8 @@
-error[E0658]: type alias impl trait is not permitted here
-  --> $DIR/issue-60407.rs:9:39
+error: fatal error triggered by #[rustc_error]
+  --> $DIR/issue-60407.rs:11:1
    |
-LL | static mut TEST: Option<Debuggable> = None;
-   |                                       ^^^^
-   |
-   = note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
-   = help: add `#![feature(impl_trait_in_bindings)]` to the crate attributes to enable
-
-error: concrete type differs from previous defining opaque type use
-  --> $DIR/issue-60407.rs:16:1
-   |
-LL | fn foo() -> Debuggable {
-   | ^^^^^^^^^^^^^^^^^^^^^^ expected `[type error]`, got `u32`
-   |
-note: previous use here
-  --> $DIR/issue-60407.rs:9:1
-   |
-LL | static mut TEST: Option<Debuggable> = None;
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | fn main() {
+   | ^^^^^^^^^
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0658`.
index afcbf313cc855497827b7f58771429416d32848e..3c6b873b4ca5a23d255f67f2c0124023678b3ae0 100644 (file)
@@ -1,18 +1,18 @@
 // revisions: min_tait full_tait
 #![feature(min_type_alias_impl_trait, rustc_attrs)]
-#![cfg_attr(full_tait, feature(type_alias_impl_trait, impl_trait_in_bindings))]
+#![cfg_attr(full_tait, feature(type_alias_impl_trait))]
 //[full_tait]~^ WARN incomplete
-//[full_tait]~| WARN incomplete
 
 type Debuggable = impl core::fmt::Debug;
 
-static mut TEST: Option<Debuggable> = None; //[min_tait]~ ERROR not permitted here
+static mut TEST: Option<Debuggable> = None;
 
 #[rustc_error]
-fn main() { //[full_tait]~ ERROR
+fn main() {
+    //~^ ERROR
     unsafe { TEST = Some(foo()) }
 }
 
-fn foo() -> Debuggable { //[min_tait]~ ERROR concrete type differs
+fn foo() -> Debuggable {
     0u32
 }
index cf668fc6e06665b87399a9724397be46d752c49c..ee26789d204f1309e6417d43167eddd432b66d98 100644 (file)
@@ -1,25 +1,17 @@
 warning: the feature `type_alias_impl_trait` is incomplete and may not be safe to use and/or cause compiler crashes
   --> $DIR/issue-65679-inst-opaque-ty-from-val-twice.rs:5:32
    |
-LL | #![cfg_attr(full_tait, feature(type_alias_impl_trait, impl_trait_in_bindings))]
+LL | #![cfg_attr(full_tait, feature(type_alias_impl_trait))]
    |                                ^^^^^^^^^^^^^^^^^^^^^
    |
    = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #63063 <https://github.com/rust-lang/rust/issues/63063> for more information
 
-warning: the feature `impl_trait_in_bindings` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/issue-65679-inst-opaque-ty-from-val-twice.rs:5:55
-   |
-LL | #![cfg_attr(full_tait, feature(type_alias_impl_trait, impl_trait_in_bindings))]
-   |                                                       ^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
-
 error: fatal error triggered by #[rustc_error]
-  --> $DIR/issue-65679-inst-opaque-ty-from-val-twice.rs:19:1
+  --> $DIR/issue-65679-inst-opaque-ty-from-val-twice.rs:18:1
    |
 LL | fn main() {
    | ^^^^^^^^^
 
-error: aborting due to previous error; 2 warnings emitted
+error: aborting due to previous error; 1 warning emitted
 
index b7f05bd83ed6e31f702afc8b0562dde717083385..d37be640e0b04a6844a3ed1a824f7689e518a3d3 100644 (file)
@@ -2,9 +2,8 @@
 
 // revisions: min_tait full_tait
 #![feature(min_type_alias_impl_trait, rustc_attrs)]
-#![cfg_attr(full_tait, feature(type_alias_impl_trait, impl_trait_in_bindings))]
+#![cfg_attr(full_tait, feature(type_alias_impl_trait))]
 //[full_tait]~^ WARN incomplete
-//[full_tait]~| WARN incomplete
 
 type T = impl Sized;
 // The concrete type referred by impl-trait-type-alias(`T`) is guaranteed
@@ -16,7 +15,8 @@
 fn take(_: fn() -> T) {}
 
 #[rustc_error]
-fn main() { //[full_tait]~ ERROR fatal error triggered by #[rustc_error]
+fn main() {
+    //[full_tait]~^ ERROR fatal error triggered by #[rustc_error]
     take(|| {});
     //[min_tait]~^ ERROR not permitted here
     take(|| {});
diff --git a/src/test/ui/type-alias-impl-trait/issue-85113.rs b/src/test/ui/type-alias-impl-trait/issue-85113.rs
deleted file mode 100644 (file)
index 0c37399..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-#![feature(min_type_alias_impl_trait)]
-#![feature(impl_trait_in_bindings)]
-#![allow(incomplete_features)]
-
-type OpaqueOutputImpl<'a> = impl Output<'a> + 'a;
-//~^ ERROR: hidden type for `impl Trait` captures lifetime that does not appear in bounds
-//~| ERROR: the type `&'<empty> str` does not fulfill the required lifetime
-//~| ERROR: cannot infer an appropriate lifetime for lifetime parameter `'a` due to conflicting requirements
-
-trait Output<'a> {}
-
-impl<'a> Output<'a> for &'a str {}
-
-fn cool_fn<'a>(arg: &'a str) -> OpaqueOutputImpl<'a> {
-    //~^ ERROR: concrete type differs from previous defining opaque type use
-    let out: OpaqueOutputImpl<'a> = arg;
-    arg
-}
-
-fn main() {
-    let s = String::from("wassup");
-    cool_fn(&s);
-}
diff --git a/src/test/ui/type-alias-impl-trait/issue-85113.stderr b/src/test/ui/type-alias-impl-trait/issue-85113.stderr
deleted file mode 100644 (file)
index 233c996..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
-  --> $DIR/issue-85113.rs:5:29
-   |
-LL | type OpaqueOutputImpl<'a> = impl Output<'a> + 'a;
-   |                             ^^^^^^^^^^^^^^^^^^^^
-   |
-note: hidden type `&'<empty> str` captures lifetime smaller than the function body
-  --> $DIR/issue-85113.rs:5:29
-   |
-LL | type OpaqueOutputImpl<'a> = impl Output<'a> + 'a;
-   |                             ^^^^^^^^^^^^^^^^^^^^
-
-error: concrete type differs from previous defining opaque type use
-  --> $DIR/issue-85113.rs:14:1
-   |
-LL | fn cool_fn<'a>(arg: &'a str) -> OpaqueOutputImpl<'a> {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&'<empty> str`, got `&'a str`
-   |
-note: previous use here
-  --> $DIR/issue-85113.rs:14:1
-   |
-LL | fn cool_fn<'a>(arg: &'a str) -> OpaqueOutputImpl<'a> {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error[E0477]: the type `&'<empty> str` does not fulfill the required lifetime
-  --> $DIR/issue-85113.rs:5:29
-   |
-LL | type OpaqueOutputImpl<'a> = impl Output<'a> + 'a;
-   |                             ^^^^^^^^^^^^^^^^^^^^
-   |
-note: type must outlive the lifetime `'a` as defined on the item at 5:23
-  --> $DIR/issue-85113.rs:5:23
-   |
-LL | type OpaqueOutputImpl<'a> = impl Output<'a> + 'a;
-   |                       ^^
-
-error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` due to conflicting requirements
-  --> $DIR/issue-85113.rs:5:29
-   |
-LL | type OpaqueOutputImpl<'a> = impl Output<'a> + 'a;
-   |                             ^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: first, the lifetime cannot outlive the empty lifetime...
-note: ...but the lifetime must also be valid for the lifetime `'a` as defined on the item at 5:23...
-  --> $DIR/issue-85113.rs:5:23
-   |
-LL | type OpaqueOutputImpl<'a> = impl Output<'a> + 'a;
-   |                       ^^
-note: ...so that the types are compatible
-  --> $DIR/issue-85113.rs:5:29
-   |
-LL | type OpaqueOutputImpl<'a> = impl Output<'a> + 'a;
-   |                             ^^^^^^^^^^^^^^^^^^^^
-   = note: expected `Output<'a>`
-              found `Output<'_>`
-
-error: aborting due to 4 previous errors
-
-Some errors have detailed explanations: E0477, E0495, E0700.
-For more information about an error, try `rustc --explain E0477`.
index 40949c84d2395dec914174b9942124a340a2be78..faddecb21766446bb7bd398efc2aec7a9ae8a4e7 100644 (file)
@@ -1,25 +1,17 @@
 warning: the feature `type_alias_impl_trait` is incomplete and may not be safe to use and/or cause compiler crashes
   --> $DIR/no_inferrable_concrete_type.rs:6:32
    |
-LL | #![cfg_attr(full_tait, feature(type_alias_impl_trait, impl_trait_in_bindings))]
+LL | #![cfg_attr(full_tait, feature(type_alias_impl_trait))]
    |                                ^^^^^^^^^^^^^^^^^^^^^
    |
    = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #63063 <https://github.com/rust-lang/rust/issues/63063> for more information
 
-warning: the feature `impl_trait_in_bindings` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/no_inferrable_concrete_type.rs:6:55
-   |
-LL | #![cfg_attr(full_tait, feature(type_alias_impl_trait, impl_trait_in_bindings))]
-   |                                                       ^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
-
 error: could not find defining uses
-  --> $DIR/no_inferrable_concrete_type.rs:10:12
+  --> $DIR/no_inferrable_concrete_type.rs:9:12
    |
 LL | type Foo = impl Copy;
    |            ^^^^^^^^^
 
-error: aborting due to previous error; 2 warnings emitted
+error: aborting due to previous error; 1 warning emitted
 
index d69e4cccdf0af6f3ff4bda9b741947fe106b6f42..3194bd7610712d77379be1be3f246e591f743677 100644 (file)
@@ -1,18 +1,8 @@
-error[E0658]: type alias impl trait is not permitted here
-  --> $DIR/no_inferrable_concrete_type.rs:16:12
-   |
-LL |     let _: Foo = std::mem::transmute(0u8);
-   |            ^^^
-   |
-   = note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
-   = help: add `#![feature(impl_trait_in_bindings)]` to the crate attributes to enable
-
 error: could not find defining uses
-  --> $DIR/no_inferrable_concrete_type.rs:10:12
+  --> $DIR/no_inferrable_concrete_type.rs:9:12
    |
 LL | type Foo = impl Copy;
    |            ^^^^^^^^^
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0658`.
index 8ff588ef278ca194dd4e8e894394cc045ca8f095..409eec7250fd0464bf0475966bb41db7718cff76 100644 (file)
@@ -3,15 +3,16 @@
 
 // revisions: min_tait full_tait
 #![feature(min_type_alias_impl_trait)]
-#![cfg_attr(full_tait, feature(type_alias_impl_trait, impl_trait_in_bindings))]
+#![cfg_attr(full_tait, feature(type_alias_impl_trait))]
 //[full_tait]~^ WARN incomplete
-//[full_tait]~| WARN incomplete
 
 type Foo = impl Copy; //~ could not find defining uses
 
 // make compiler happy about using 'Foo'
-fn bar(x: Foo) -> Foo { x }
+fn bar(x: Foo) -> Foo {
+    x
+}
 
 fn main() {
-    let _: Foo = std::mem::transmute(0u8); //[min_tait]~ ERROR not permitted here
+    let _: Foo = std::mem::transmute(0u8);
 }
index b560c0c918a86df37acd223d89a2b04776fe7152..d5a4fa52dfb7b81fd6ab5498ab20201c884e64bd 100644 (file)
@@ -1,25 +1,17 @@
 warning: the feature `type_alias_impl_trait` is incomplete and may not be safe to use and/or cause compiler crashes
   --> $DIR/structural-match-no-leak.rs:4:32
    |
-LL | #![cfg_attr(full_tait, feature(type_alias_impl_trait, impl_trait_in_bindings))]
+LL | #![cfg_attr(full_tait, feature(type_alias_impl_trait))]
    |                                ^^^^^^^^^^^^^^^^^^^^^
    |
    = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #63063 <https://github.com/rust-lang/rust/issues/63063> for more information
 
-warning: the feature `impl_trait_in_bindings` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/structural-match-no-leak.rs:4:55
-   |
-LL | #![cfg_attr(full_tait, feature(type_alias_impl_trait, impl_trait_in_bindings))]
-   |                                                       ^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
-
 error: `impl Send` cannot be used in patterns
-  --> $DIR/structural-match-no-leak.rs:19:9
+  --> $DIR/structural-match-no-leak.rs:18:9
    |
 LL |         LEAK_FREE => (),
    |         ^^^^^^^^^
 
-error: aborting due to previous error; 2 warnings emitted
+error: aborting due to previous error; 1 warning emitted
 
index e962b23a587de1dc7d8725ba9919d5c5b785d482..b7caf8ed2986896cab867d5b85b1332a90dc2317 100644 (file)
@@ -1,12 +1,8 @@
-error[E0658]: type alias impl trait is not permitted here
-  --> $DIR/structural-match-no-leak.rs:15:24
+error: `impl Send` cannot be used in patterns
+  --> $DIR/structural-match-no-leak.rs:18:9
    |
-LL | const LEAK_FREE: Bar = leak_free();
-   |                        ^^^^^^^^^^^
-   |
-   = note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
-   = help: add `#![feature(impl_trait_in_bindings)]` to the crate attributes to enable
+LL |         LEAK_FREE => (),
+   |         ^^^^^^^^^
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0658`.
index d0bae30f9963f5231086df4278a4b1f3c543b5da..e2b10e7355fbb820a339b0805ff9c88d87e929e3 100644 (file)
@@ -1,9 +1,8 @@
 #![feature(const_impl_trait)]
 // revisions: min_tait full_tait
 #![feature(min_type_alias_impl_trait)]
-#![cfg_attr(full_tait, feature(type_alias_impl_trait, impl_trait_in_bindings))]
+#![cfg_attr(full_tait, feature(type_alias_impl_trait))]
 //[full_tait]~^ WARN incomplete
-//[full_tait]~| WARN incomplete
 
 type Bar = impl Send;
 
 const fn leak_free() -> Bar {
     7i32
 }
-const LEAK_FREE: Bar = leak_free(); //[min_tait]~ ERROR not permitted here
+const LEAK_FREE: Bar = leak_free();
 
 fn leak_free_test() {
     match todo!() {
         LEAK_FREE => (),
-        //[full_tait]~^ `impl Send` cannot be used in patterns
+        //~^ `impl Send` cannot be used in patterns
         _ => (),
     }
 }
index b94e06e6d0ef40222aaa33da3c71016ebe34ab7f..d394c99df80293c1f9df69d145479ddb0445892d 100644 (file)
@@ -1,25 +1,17 @@
 warning: the feature `type_alias_impl_trait` is incomplete and may not be safe to use and/or cause compiler crashes
   --> $DIR/structural-match.rs:4:32
    |
-LL | #![cfg_attr(full_tait, feature(type_alias_impl_trait, impl_trait_in_bindings))]
+LL | #![cfg_attr(full_tait, feature(type_alias_impl_trait))]
    |                                ^^^^^^^^^^^^^^^^^^^^^
    |
    = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #63063 <https://github.com/rust-lang/rust/issues/63063> for more information
 
-warning: the feature `impl_trait_in_bindings` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/structural-match.rs:4:55
-   |
-LL | #![cfg_attr(full_tait, feature(type_alias_impl_trait, impl_trait_in_bindings))]
-   |                                                       ^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
-
 error: `impl Send` cannot be used in patterns
-  --> $DIR/structural-match.rs:20:9
+  --> $DIR/structural-match.rs:19:9
    |
 LL |         VALUE => (),
    |         ^^^^^
 
-error: aborting due to previous error; 2 warnings emitted
+error: aborting due to previous error; 1 warning emitted
 
index 36c49a954bda8a0fc449071cec8c8f45659f3e8d..f63b1fb23df7e67003203de2aa1a56ff22d5f8c0 100644 (file)
@@ -1,12 +1,8 @@
-error[E0658]: type alias impl trait is not permitted here
-  --> $DIR/structural-match.rs:16:20
+error: `impl Send` cannot be used in patterns
+  --> $DIR/structural-match.rs:19:9
    |
-LL | const VALUE: Foo = value();
-   |                    ^^^^^^^
-   |
-   = note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
-   = help: add `#![feature(impl_trait_in_bindings)]` to the crate attributes to enable
+LL |         VALUE => (),
+   |         ^^^^^
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0658`.
index daf914cc494aca84e3d7b972f27d73960978d9f5..aed9334b3cc86825b00004ca5d1bf0fcaa1ed8ae 100644 (file)
@@ -1,9 +1,8 @@
 #![feature(const_impl_trait)]
 // revisions: min_tait full_tait
 #![feature(min_type_alias_impl_trait)]
-#![cfg_attr(full_tait, feature(type_alias_impl_trait, impl_trait_in_bindings))]
+#![cfg_attr(full_tait, feature(type_alias_impl_trait))]
 //[full_tait]~^ WARN incomplete
-//[full_tait]~| WARN incomplete
 
 type Foo = impl Send;
 
 const fn value() -> Foo {
     A
 }
-const VALUE: Foo = value(); //[min_tait]~ ERROR not permitted here
+const VALUE: Foo = value();
 
 fn test() {
     match todo!() {
         VALUE => (),
-        //[full_tait]~^ `impl Send` cannot be used in patterns
+        //~^ `impl Send` cannot be used in patterns
         _ => (),
     }
 }
index 894d61502a7210be8d97bf91d135eae9eb0df55c..6f817757cc4b3c3d798167cc2d4b5bb6d7de647a 100644 (file)
@@ -1,5 +1,5 @@
 warning: the feature `type_alias_impl_trait` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/type-alias-impl-trait-const.rs:5:32
+  --> $DIR/type-alias-impl-trait-const.rs:3:32
    |
 LL | #![cfg_attr(full_tait, feature(type_alias_impl_trait))]
    |                                ^^^^^^^^^^^^^^^^^^^^^
@@ -7,13 +7,24 @@ LL | #![cfg_attr(full_tait, feature(type_alias_impl_trait))]
    = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #63063 <https://github.com/rust-lang/rust/issues/63063> for more information
 
-warning: the feature `impl_trait_in_bindings` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/type-alias-impl-trait-const.rs:11:12
+error[E0308]: mismatched types
+  --> $DIR/type-alias-impl-trait-const.rs:13:19
    |
-LL | #![feature(impl_trait_in_bindings)]
-   |            ^^^^^^^^^^^^^^^^^^^^^^
+LL | pub type Foo = impl Debug;
+   |                ---------- the expected opaque type
+...
+LL | const _FOO: Foo = 5;
+   |                   ^ expected opaque type, found integer
    |
-   = note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
+   = note: expected opaque type `impl Debug`
+                     found type `{integer}`
 
-warning: 2 warnings emitted
+error: could not find defining uses
+  --> $DIR/type-alias-impl-trait-const.rs:10:16
+   |
+LL | pub type Foo = impl Debug;
+   |                ^^^^^^^^^^
+
+error: aborting due to 2 previous errors; 1 warning emitted
 
+For more information about this error, try `rustc --explain E0308`.
index 66e4c242168d151e67314eb6915048c511f75c49..ce98318333b01687b81b9a35ec187501aa95d572 100644 (file)
@@ -1,11 +1,21 @@
-warning: the feature `impl_trait_in_bindings` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/type-alias-impl-trait-const.rs:11:12
+error[E0308]: mismatched types
+  --> $DIR/type-alias-impl-trait-const.rs:13:19
    |
-LL | #![feature(impl_trait_in_bindings)]
-   |            ^^^^^^^^^^^^^^^^^^^^^^
+LL | pub type Foo = impl Debug;
+   |                ---------- the expected opaque type
+...
+LL | const _FOO: Foo = 5;
+   |                   ^ expected opaque type, found integer
    |
-   = note: `#[warn(incomplete_features)]` on by default
-   = note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
+   = note: expected opaque type `impl Debug`
+                     found type `{integer}`
 
-warning: 1 warning emitted
+error: could not find defining uses
+  --> $DIR/type-alias-impl-trait-const.rs:10:16
+   |
+LL | pub type Foo = impl Debug;
+   |                ^^^^^^^^^^
+
+error: aborting due to 2 previous errors
 
+For more information about this error, try `rustc --explain E0308`.
index 0b0551cd96d3b9cd445e4330c5d786dd092d80c2..751512c5dfc03b58561a6b33b3c9ffee5b7e827e 100644 (file)
@@ -1,23 +1,16 @@
-// check-pass
-
 // revisions: min_tait full_tait
 #![feature(min_type_alias_impl_trait)]
 #![cfg_attr(full_tait, feature(type_alias_impl_trait))]
 //[full_tait]~^ WARN incomplete
-// Currently, the `type_alias_impl_trait` feature implicitly
-// depends on `impl_trait_in_bindings` in order to work properly.
-// Specifically, this line requires `impl_trait_in_bindings` to be enabled:
-// https://github.com/rust-lang/rust/blob/481068a707679257e2a738b40987246e0420e787/compiler/rustc_typeck/check/mod.rs#L856
-#![feature(impl_trait_in_bindings)]
-//~^ WARN the feature `impl_trait_in_bindings` is incomplete
 
 // Ensures that `const` items can constrain an opaque `impl Trait`.
 
 use std::fmt::Debug;
 
 pub type Foo = impl Debug;
+//~^ ERROR could not find defining uses
 
 const _FOO: Foo = 5;
+//~^ ERROR mismatched types [E0308]
 
-fn main() {
-}
+fn main() {}
index ddfa31cf6244807f76f90594794b2ce33e7910e6..adf3fa2c8074820084d87d85c672aaa2953271de 100644 (file)
@@ -23,28 +23,37 @@ error[E0277]: the trait bound `String: Copy` is not satisfied
   --> $DIR/type-check-defaults.rs:11:17
    |
 LL | struct Bounds<T:Copy=String>(T);
-   | ----------------^^^^------------
-   | |               |
-   | |               the trait `Copy` is not implemented for `String`
-   | required by `Bounds`
+   |                 ^^^^ the trait `Copy` is not implemented for `String`
+   |
+note: required by `Bounds`
+  --> $DIR/type-check-defaults.rs:11:1
+   |
+LL | struct Bounds<T:Copy=String>(T);
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `String: Copy` is not satisfied
   --> $DIR/type-check-defaults.rs:14:42
    |
 LL | struct WhereClause<T=String>(T) where T: Copy;
-   | -----------------------------------------^^^^-
-   | |                                        |
-   | |                                        the trait `Copy` is not implemented for `String`
-   | required by `WhereClause`
+   |                                          ^^^^ the trait `Copy` is not implemented for `String`
+   |
+note: required by `WhereClause`
+  --> $DIR/type-check-defaults.rs:14:1
+   |
+LL | struct WhereClause<T=String>(T) where T: Copy;
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `String: Copy` is not satisfied
   --> $DIR/type-check-defaults.rs:17:20
    |
 LL | trait TraitBound<T:Copy=String> {}
-   | -------------------^^^^--------
-   | |                  |
-   | |                  the trait `Copy` is not implemented for `String`
-   | required by `TraitBound`
+   |                    ^^^^ the trait `Copy` is not implemented for `String`
+   |
+note: required by `TraitBound`
+  --> $DIR/type-check-defaults.rs:17:1
+   |
+LL | trait TraitBound<T:Copy=String> {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `T: Copy` is not satisfied
   --> $DIR/type-check-defaults.rs:21:25
@@ -63,12 +72,14 @@ error[E0277]: cannot add `u8` to `i32`
   --> $DIR/type-check-defaults.rs:24:66
    |
 LL | trait ProjectionPred<T:Iterator = IntoIter<i32>> where T::Item : Add<u8> {}
-   | -----------------------------------------------------------------^^^^^^^
-   | |                                                                |
-   | |                                                                no implementation for `i32 + u8`
-   | required by `ProjectionPred`
+   |                                                                  ^^^^^^^ no implementation for `i32 + u8`
    |
    = help: the trait `Add<u8>` is not implemented for `i32`
+note: required by `ProjectionPred`
+  --> $DIR/type-check-defaults.rs:24:1
+   |
+LL | trait ProjectionPred<T:Iterator = IntoIter<i32>> where T::Item : Add<u8> {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 7 previous errors
 
index e0039f2a316026c57f3a6a298d06cb98cc60a8d7..a6b41520d67b1841786a40990f0c81e66287189b 100644 (file)
@@ -1,12 +1,14 @@
 error[E0277]: the trait bound `Self: Tr<U>` is not satisfied
   --> $DIR/type-params-in-different-spaces-2.rs:10:9
    |
-LL |     fn op(_: T) -> Self;
-   |     -------------------- required by `Tr::op`
-...
 LL |         Tr::op(u)
    |         ^^^^^^ the trait `Tr<U>` is not implemented for `Self`
    |
+note: required by `Tr::op`
+  --> $DIR/type-params-in-different-spaces-2.rs:5:5
+   |
+LL |     fn op(_: T) -> Self;
+   |     ^^^^^^^^^^^^^^^^^^^^
 help: consider further restricting `Self`
    |
 LL |     fn test<U>(u: U) -> Self where Self: Tr<U> {
@@ -15,12 +17,14 @@ LL |     fn test<U>(u: U) -> Self where Self: Tr<U> {
 error[E0277]: the trait bound `Self: Tr<U>` is not satisfied
   --> $DIR/type-params-in-different-spaces-2.rs:16:9
    |
-LL |     fn op(_: T) -> Self;
-   |     -------------------- required by `Tr::op`
-...
 LL |         Tr::op(u)
    |         ^^^^^^ the trait `Tr<U>` is not implemented for `Self`
    |
+note: required by `Tr::op`
+  --> $DIR/type-params-in-different-spaces-2.rs:5:5
+   |
+LL |     fn op(_: T) -> Self;
+   |     ^^^^^^^^^^^^^^^^^^^^
 help: consider further restricting `Self`
    |
 LL |     fn test<U>(u: U) -> Self where Self: Tr<U> {
index a2bf963044582278e921e1872847b920b8de665f..e30e4f5e7d3fd9caea78d069b224b8c6a521d9f8 100644 (file)
@@ -5,7 +5,11 @@ LL |     <i32 as Add<u32>>::add(1, 2);
    |     ^^^^^^^^^^^^^^^^^^^^^^ no implementation for `i32 + u32`
    |
    = help: the trait `Add<u32>` is not implemented for `i32`
-   = note: required by `add`
+note: required by `add`
+  --> $SRC_DIR/core/src/ops/arith.rs:LL:COL
+   |
+LL |     fn add(self, rhs: Rhs) -> Self::Output;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0308]: mismatched types
   --> $DIR/ufcs-qpath-self-mismatch.rs:6:28
index 2079f6fd53173d7ddd713634e7f11b79e3c8d0ad..be6ed8d56232e6b454300e0f38d73698926b3d6e 100644 (file)
@@ -1,14 +1,16 @@
 error[E0277]: the trait bound `[(); 0]: Foo` is not satisfied
   --> $DIR/unevaluated_fixed_size_array_len.rs:12:5
    |
-LL |     fn foo();
-   |     --------- required by `Foo::foo`
-...
 LL |     <[(); 0] as Foo>::foo()
    |     ^^^^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `[(); 0]`
    |
    = help: the following implementations were found:
              <[(); 1] as Foo>
+note: required by `Foo::foo`
+  --> $DIR/unevaluated_fixed_size_array_len.rs:4:5
+   |
+LL |     fn foo();
+   |     ^^^^^^^^^
 
 error: aborting due to previous error
 
index 9477d8470fc6f6dd9ff7edc81818097b14b8c244..c2fd8545f63ada897814cd02881adeb6f4107b64 100644 (file)
@@ -1,6 +1,9 @@
 error[E0277]: the trait bound `PartialEqNotEq: Eq` is not satisfied
   --> $DIR/union-derive-eq.rs:16:5
    |
+LL | #[derive(Eq)]
+   |          -- in this derive macro expansion
+LL | union U2 {
 LL |     a: PartialEqNotEq,
    |     ^^^^^^^^^^^^^^^^^ the trait `Eq` is not implemented for `PartialEqNotEq`
    | 
index 9477d8470fc6f6dd9ff7edc81818097b14b8c244..c2fd8545f63ada897814cd02881adeb6f4107b64 100644 (file)
@@ -1,6 +1,9 @@
 error[E0277]: the trait bound `PartialEqNotEq: Eq` is not satisfied
   --> $DIR/union-derive-eq.rs:16:5
    |
+LL | #[derive(Eq)]
+   |          -- in this derive macro expansion
+LL | union U2 {
 LL |     a: PartialEqNotEq,
    |     ^^^^^^^^^^^^^^^^^ the trait `Eq` is not implemented for `PartialEqNotEq`
    | 
index fcd0bdec25833321601a990d84a1224e1c421007..cd8577818647a9036b849eba4a88d3503b7824e3 100644 (file)
@@ -1,20 +1,26 @@
 error[E0277]: the trait bound `Rc<u32>: Copy` is not satisfied
   --> $DIR/union-generic.rs:11:13
    |
-LL | union U<T: Copy> {
-   | ---------------- required by `U`
-...
 LL |     let u = U { a: Rc::new(0u32) };
    |             ^ the trait `Copy` is not implemented for `Rc<u32>`
+   |
+note: required by `U`
+  --> $DIR/union-generic.rs:6:1
+   |
+LL | union U<T: Copy> {
+   | ^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `Rc<u32>: Copy` is not satisfied
   --> $DIR/union-generic.rs:13:13
    |
-LL | union U<T: Copy> {
-   | ---------------- required by `U`
-...
 LL |     let u = U::<Rc<u32>> { a: Default::default() };
    |             ^^^^^^^^^^^^ the trait `Copy` is not implemented for `Rc<u32>`
+   |
+note: required by `U`
+  --> $DIR/union-generic.rs:6:1
+   |
+LL | union U<T: Copy> {
+   | ^^^^^^^^^^^^^^^^
 
 error: aborting due to 2 previous errors
 
index fcd0bdec25833321601a990d84a1224e1c421007..cd8577818647a9036b849eba4a88d3503b7824e3 100644 (file)
@@ -1,20 +1,26 @@
 error[E0277]: the trait bound `Rc<u32>: Copy` is not satisfied
   --> $DIR/union-generic.rs:11:13
    |
-LL | union U<T: Copy> {
-   | ---------------- required by `U`
-...
 LL |     let u = U { a: Rc::new(0u32) };
    |             ^ the trait `Copy` is not implemented for `Rc<u32>`
+   |
+note: required by `U`
+  --> $DIR/union-generic.rs:6:1
+   |
+LL | union U<T: Copy> {
+   | ^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `Rc<u32>: Copy` is not satisfied
   --> $DIR/union-generic.rs:13:13
    |
-LL | union U<T: Copy> {
-   | ---------------- required by `U`
-...
 LL |     let u = U::<Rc<u32>> { a: Default::default() };
    |             ^^^^^^^^^^^^ the trait `Copy` is not implemented for `Rc<u32>`
+   |
+note: required by `U`
+  --> $DIR/union-generic.rs:6:1
+   |
+LL | union U<T: Copy> {
+   | ^^^^^^^^^^^^^^^^
 
 error: aborting due to 2 previous errors
 
index a0eb7d10bd94a0ab61200d679765757bf4369659..f6b48938f9b04437bf699c469ca51c284f135498 100644 (file)
@@ -1,8 +1,11 @@
 error[E0277]: the trait bound `(): Foo` is not satisfied
-  --> $DIR/wf-foreign-fn-decl-ret.rs:11:12
+  --> $DIR/wf-foreign-fn-decl-ret.rs:11:25
    |
+LL | pub trait Foo {
+   | ------------- required by this bound in `Foo`
+...
 LL |     pub fn lint_me() -> <() as Foo>::Assoc;
-   |            ^^^^^^^ the trait `Foo` is not implemented for `()`
+   |                         ^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `()`
 
 error[E0277]: the trait bound `u32: Unsatisfied` is not satisfied
   --> $DIR/wf-foreign-fn-decl-ret.rs:14:32
index 9687658feba43b50936900e63c938265b4957242..ca90e9222dea9c9f29773f7a5153a9cd4ddbc47b 100644 (file)
@@ -1,11 +1,11 @@
 error[E0277]: the trait bound `T: Copy` is not satisfied
-  --> $DIR/wf-in-fn-arg.rs:10:14
+  --> $DIR/wf-in-fn-arg.rs:10:15
    |
 LL | struct MustBeCopy<T:Copy> {
    |                     ---- required by this bound in `MustBeCopy`
 ...
 LL | fn bar<T>(_: &MustBeCopy<T>)
-   |              ^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `T`
+   |               ^^^^^^^^^^^^^ the trait `Copy` is not implemented for `T`
    |
 help: consider restricting type parameter `T`
    |
index 8386959cfb3a83327850c86e6386ffb8ed97c185..4fcf8f403bbb6e38ac9da13de6627395f38a7c15 100644 (file)
@@ -13,5 +13,5 @@ pub trait Trait {}
 impl Trait for Ref {} //~ ERROR:  implicit elided lifetime not allowed here
 
 extern "C" {
-    pub fn repro(_: Wrapper<Ref>); //~ ERROR: mismatched types
+    pub fn repro(_: Wrapper<Ref>); //~ ERROR: incompatible lifetime on type
 }
index bb839d0a5eca685438a24a35def594c617ddc182..4e927cd983d0d4d906defe475a6d98e19fe3c4cc 100644 (file)
@@ -3,22 +3,30 @@ error[E0726]: implicit elided lifetime not allowed here
    |
 LL | impl Trait for Ref {}
    |                ^^^- help: indicate the anonymous lifetime: `<'_>`
+   |
+   = note: assuming a `'static` lifetime...
 
-error[E0308]: mismatched types
+error: incompatible lifetime on type
   --> $DIR/wf-in-foreign-fn-decls-issue-80468.rs:16:21
    |
 LL |     pub fn repro(_: Wrapper<Ref>);
-   |                     ^^^^^^^^^^^^ lifetime mismatch
+   |                     ^^^^^^^^^^^^
+   |
+note: because this has an unmet lifetime requirement
+  --> $DIR/wf-in-foreign-fn-decls-issue-80468.rs:8:23
    |
-   = note: expected trait `Trait`
-              found trait `Trait`
+LL | pub struct Wrapper<T: Trait>(T);
+   |                       ^^^^^ introduces a `'static` lifetime requirement
 note: the anonymous lifetime #1 defined on the method body at 16:5...
   --> $DIR/wf-in-foreign-fn-decls-issue-80468.rs:16:5
    |
 LL |     pub fn repro(_: Wrapper<Ref>);
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = note: ...does not necessarily outlive the static lifetime
+note: ...does not necessarily outlive the static lifetime introduced by the compatible `impl`
+  --> $DIR/wf-in-foreign-fn-decls-issue-80468.rs:13:1
+   |
+LL | impl Trait for Ref {}
+   | ^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0308`.
index c3d5d2b9669b80edd54c11e24b8ca3519e6d816a..2a129538f76333bbfb69cf8b829a255f8947227a 100644 (file)
@@ -1,11 +1,11 @@
 error[E0277]: the trait bound `Self: Eq` is not satisfied
-  --> $DIR/wf-trait-default-fn-arg.rs:11:22
+  --> $DIR/wf-trait-default-fn-arg.rs:11:23
    |
 LL | struct Bar<T:Eq+?Sized> { value: Box<T> }
    |              -- required by this bound in `Bar`
 ...
 LL |     fn bar(&self, x: &Bar<Self>) {
-   |                      ^^^^^^^^^^ the trait `Eq` is not implemented for `Self`
+   |                       ^^^^^^^^^ the trait `Eq` is not implemented for `Self`
    |
 help: consider further restricting `Self`
    |
index 4510f50feea58871f3e8bd03638732e613d85f36..7693aa6d2d583ed64a597ddc705a1488cea19216 100644 (file)
@@ -1,11 +1,11 @@
 error[E0277]: the trait bound `Self: Eq` is not satisfied
-  --> $DIR/wf-trait-fn-arg.rs:10:22
+  --> $DIR/wf-trait-fn-arg.rs:10:23
    |
 LL | struct Bar<T:Eq+?Sized> { value: Box<T> }
    |              -- required by this bound in `Bar`
 ...
 LL |     fn bar(&self, x: &Bar<Self>);
-   |                      ^^^^^^^^^^ the trait `Eq` is not implemented for `Self`
+   |                       ^^^^^^^^^ the trait `Eq` is not implemented for `Self`
    |
 help: consider further restricting `Self`
    |
index 8b7e43ccc04e90e4f566ede7d44dbebd68e9da48..69b414cc8f92363ff1bcac98f75dee6f7507f796 100644 (file)
@@ -3,12 +3,22 @@ error[E0624]: associated function `static_meth_struct` is private
    |
 LL |     let _ = xc_private_method_lib::Struct::static_meth_struct();
    |                                            ^^^^^^^^^^^^^^^^^^ private associated function
+   | 
+  ::: $DIR/auxiliary/xc-private-method-lib.rs:8:5
+   |
+LL |     fn static_meth_struct() -> Struct {
+   |     --------------------------------- private associated function defined here
 
 error[E0624]: associated function `static_meth_enum` is private
   --> $DIR/xc-private-method.rs:9:42
    |
 LL |     let _ = xc_private_method_lib::Enum::static_meth_enum();
    |                                          ^^^^^^^^^^^^^^^^ private associated function
+   | 
+  ::: $DIR/auxiliary/xc-private-method-lib.rs:23:5
+   |
+LL |     fn static_meth_enum() -> Enum {
+   |     ----------------------------- private associated function defined here
 
 error: aborting due to 2 previous errors
 
index 0ebdb0a06d82b45340ec2ecf3c4c1d9a2f55f37a..685ce0e0a186fc668d92225936fadd30e22ec8ed 100644 (file)
@@ -3,12 +3,22 @@ error[E0624]: associated function `meth_struct` is private
    |
 LL |     let _ = xc_private_method_lib::Struct{ x: 10 }.meth_struct();
    |                                                    ^^^^^^^^^^^ private associated function
+   | 
+  ::: $DIR/auxiliary/xc-private-method-lib.rs:12:5
+   |
+LL |     fn meth_struct(&self) -> isize {
+   |     ------------------------------ private associated function defined here
 
 error[E0624]: associated function `meth_enum` is private
   --> $DIR/xc-private-method2.rs:9:55
    |
 LL |     let _ = xc_private_method_lib::Enum::Variant1(20).meth_enum();
    |                                                       ^^^^^^^^^ private associated function
+   | 
+  ::: $DIR/auxiliary/xc-private-method-lib.rs:27:5
+   |
+LL |     fn meth_enum(&self) -> isize {
+   |     ---------------------------- private associated function defined here
 
 error: aborting due to 2 previous errors
 
index 27277d966b3cfa454d6dea7f724cb961c036251c..4e143fd131e0c16cefd008456e974236ca54e62e 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 27277d966b3cfa454d6dea7f724cb961c036251c
+Subproject commit 4e143fd131e0c16cefd008456e974236ca54e62e
index 9f89f74e7450361f45def111ae1aeea75ef3e328..5e00dec2e775f064b31ffd75dd2054e7c4366294 100644 (file)
@@ -2772,6 +2772,7 @@ Released 2018-09-13
 [`same_item_push`]: https://rust-lang.github.io/rust-clippy/master/index.html#same_item_push
 [`search_is_some`]: https://rust-lang.github.io/rust-clippy/master/index.html#search_is_some
 [`self_assignment`]: https://rust-lang.github.io/rust-clippy/master/index.html#self_assignment
+[`self_named_constructor`]: https://rust-lang.github.io/rust-clippy/master/index.html#self_named_constructor
 [`semicolon_if_nothing_returned`]: https://rust-lang.github.io/rust-clippy/master/index.html#semicolon_if_nothing_returned
 [`serde_api_misuse`]: https://rust-lang.github.io/rust-clippy/master/index.html#serde_api_misuse
 [`shadow_reuse`]: https://rust-lang.github.io/rust-clippy/master/index.html#shadow_reuse
index a8c527fe2e353fd131defe916887f5fd8cdd6f05..17ce3cd809f6fcb9e88618b955750b5fd9372516 100644 (file)
@@ -1,8 +1,8 @@
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::source::snippet_opt;
 use clippy_utils::ty::implements_trait;
-use clippy_utils::{eq_expr_value, get_trait_def_id, trait_ref_of_method};
-use clippy_utils::{higher, paths, sugg};
+use clippy_utils::{binop_traits, sugg};
+use clippy_utils::{eq_expr_value, trait_ref_of_method};
 use if_chain::if_chain;
 use rustc_errors::Applicability;
 use rustc_hir as hir;
@@ -85,71 +85,34 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>) {
                     let lint = |assignee: &hir::Expr<'_>, rhs: &hir::Expr<'_>| {
                         let ty = cx.typeck_results().expr_ty(assignee);
                         let rty = cx.typeck_results().expr_ty(rhs);
-                        macro_rules! ops {
-                            ($op:expr,
-                             $cx:expr,
-                             $ty:expr,
-                             $rty:expr,
-                             $($trait_name:ident),+) => {
-                                match $op {
-                                    $(hir::BinOpKind::$trait_name => {
-                                        let [krate, module] = paths::OPS_MODULE;
-                                        let path: [&str; 3] = [krate, module, concat!(stringify!($trait_name), "Assign")];
-                                        let trait_id = if let Some(trait_id) = get_trait_def_id($cx, &path) {
-                                            trait_id
-                                        } else {
-                                            return; // useless if the trait doesn't exist
-                                        };
-                                        // check that we are not inside an `impl AssignOp` of this exact operation
-                                        let parent_fn = cx.tcx.hir().get_parent_item(e.hir_id);
-                                        if_chain! {
-                                            if let Some(trait_ref) = trait_ref_of_method(cx, parent_fn);
-                                            if trait_ref.path.res.def_id() == trait_id;
-                                            then { return; }
+                        if_chain! {
+                            if let Some((_, lang_item)) = binop_traits(op.node);
+                            if let Ok(trait_id) = cx.tcx.lang_items().require(lang_item);
+                            let parent_fn = cx.tcx.hir().get_parent_item(e.hir_id);
+                            if trait_ref_of_method(cx, parent_fn)
+                                .map_or(true, |t| t.path.res.def_id() != trait_id);
+                            if implements_trait(cx, ty, trait_id, &[rty.into()]);
+                            then {
+                                span_lint_and_then(
+                                    cx,
+                                    ASSIGN_OP_PATTERN,
+                                    expr.span,
+                                    "manual implementation of an assign operation",
+                                    |diag| {
+                                        if let (Some(snip_a), Some(snip_r)) =
+                                            (snippet_opt(cx, assignee.span), snippet_opt(cx, rhs.span))
+                                        {
+                                            diag.span_suggestion(
+                                                expr.span,
+                                                "replace it with",
+                                                format!("{} {}= {}", snip_a, op.node.as_str(), snip_r),
+                                                Applicability::MachineApplicable,
+                                            );
                                         }
-                                        implements_trait($cx, $ty, trait_id, &[$rty])
-                                    },)*
-                                    _ => false,
-                                }
+                                    },
+                                );
                             }
                         }
-                        if ops!(
-                            op.node,
-                            cx,
-                            ty,
-                            rty.into(),
-                            Add,
-                            Sub,
-                            Mul,
-                            Div,
-                            Rem,
-                            And,
-                            Or,
-                            BitAnd,
-                            BitOr,
-                            BitXor,
-                            Shr,
-                            Shl
-                        ) {
-                            span_lint_and_then(
-                                cx,
-                                ASSIGN_OP_PATTERN,
-                                expr.span,
-                                "manual implementation of an assign operation",
-                                |diag| {
-                                    if let (Some(snip_a), Some(snip_r)) =
-                                        (snippet_opt(cx, assignee.span), snippet_opt(cx, rhs.span))
-                                    {
-                                        diag.span_suggestion(
-                                            expr.span,
-                                            "replace it with",
-                                            format!("{} {}= {}", snip_a, op.node.as_str(), snip_r),
-                                            Applicability::MachineApplicable,
-                                        );
-                                    }
-                                },
-                            );
-                        }
                     };
 
                     let mut visitor = ExprVisitor {
@@ -206,7 +169,7 @@ fn lint_misrefactored_assign_op(
             if let (Some(snip_a), Some(snip_r)) = (snippet_opt(cx, assignee.span), snippet_opt(cx, rhs_other.span)) {
                 let a = &sugg::Sugg::hir(cx, assignee, "..");
                 let r = &sugg::Sugg::hir(cx, rhs, "..");
-                let long = format!("{} = {}", snip_a, sugg::make_binop(higher::binop(op.node), a, r));
+                let long = format!("{} = {}", snip_a, sugg::make_binop(op.node.into(), a, r));
                 diag.span_suggestion(
                     expr.span,
                     &format!(
index a3a8e748d99a0f5a261f3bf8806c3063607cd50b..d39cabfb2825beb141d1afacd5cecde3b087866d 100644 (file)
@@ -102,7 +102,7 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) {
             if macro_with_not_op(&left.kind) || macro_with_not_op(&right.kind) {
                 return;
             }
-            if is_useless_with_eq_exprs(higher::binop(op.node)) && eq_expr_value(cx, left, right) {
+            if is_useless_with_eq_exprs(op.node.into()) && eq_expr_value(cx, left, right) {
                 span_lint(
                     cx,
                     EQ_OP,
index 1af3a215f4468b4211bd7aa28a1e74ce8648604f..aa763b5c5e666f9120e067c2d151d4a93f3a9fc6 100644 (file)
@@ -330,6 +330,7 @@ macro_rules! declare_clippy_lint {
 mod repeat_once;
 mod returns;
 mod self_assignment;
+mod self_named_constructor;
 mod semicolon_if_nothing_returned;
 mod serde_api;
 mod shadow;
@@ -900,6 +901,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
         returns::LET_AND_RETURN,
         returns::NEEDLESS_RETURN,
         self_assignment::SELF_ASSIGNMENT,
+        self_named_constructor::SELF_NAMED_CONSTRUCTOR,
         semicolon_if_nothing_returned::SEMICOLON_IF_NOTHING_RETURNED,
         serde_api::SERDE_API_MISUSE,
         shadow::SHADOW_REUSE,
@@ -1406,6 +1408,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
         LintId::of(returns::LET_AND_RETURN),
         LintId::of(returns::NEEDLESS_RETURN),
         LintId::of(self_assignment::SELF_ASSIGNMENT),
+        LintId::of(self_named_constructor::SELF_NAMED_CONSTRUCTOR),
         LintId::of(serde_api::SERDE_API_MISUSE),
         LintId::of(single_component_path_imports::SINGLE_COMPONENT_PATH_IMPORTS),
         LintId::of(size_of_in_element_count::SIZE_OF_IN_ELEMENT_COUNT),
@@ -1559,6 +1562,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
         LintId::of(redundant_static_lifetimes::REDUNDANT_STATIC_LIFETIMES),
         LintId::of(returns::LET_AND_RETURN),
         LintId::of(returns::NEEDLESS_RETURN),
+        LintId::of(self_named_constructor::SELF_NAMED_CONSTRUCTOR),
         LintId::of(single_component_path_imports::SINGLE_COMPONENT_PATH_IMPORTS),
         LintId::of(tabs_in_doc_comments::TABS_IN_DOC_COMMENTS),
         LintId::of(to_digit_is_some::TO_DIGIT_IS_SOME),
@@ -2101,6 +2105,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
     let scripts = conf.allowed_scripts.clone();
     store.register_early_pass(move || box disallowed_script_idents::DisallowedScriptIdents::new(&scripts));
     store.register_late_pass(|| box strlen_on_c_strings::StrlenOnCStrings);
+    store.register_late_pass(move || box self_named_constructor::SelfNamedConstructor);
 }
 
 #[rustfmt::skip]
index 6d5ce3373f79d523060a219922875acf3a3cec7c..66e3d957894173317445026cbc24a76f9d50b095 100644 (file)
@@ -721,7 +721,7 @@ fn check_single_match_single_pattern(
     expr: &Expr<'_>,
     els: Option<&Expr<'_>>,
 ) {
-    if is_wild(&arms[1].pat) {
+    if is_wild(arms[1].pat) {
         report_single_match_single_pattern(cx, ex, arms, expr, els);
     }
 }
@@ -1287,7 +1287,7 @@ fn find_matches_sugg(cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>], expr
         if let Some((b1_arm, b0_arms)) = arms.split_last();
         if let Some(b0) = find_bool_lit(&b0_arms[0].body.kind, desugared);
         if let Some(b1) = find_bool_lit(&b1_arm.body.kind, desugared);
-        if is_wild(&b1_arm.pat);
+        if is_wild(b1_arm.pat);
         if b0 != b1;
         let if_guard = &b0_arms[0].guard;
         if if_guard.is_none() || b0_arms.len() == 1;
diff --git a/src/tools/clippy/clippy_lints/src/self_named_constructor.rs b/src/tools/clippy/clippy_lints/src/self_named_constructor.rs
new file mode 100644 (file)
index 0000000..da991e1
--- /dev/null
@@ -0,0 +1,91 @@
+use clippy_utils::diagnostics::span_lint;
+use clippy_utils::return_ty;
+use clippy_utils::ty::{contains_adt_constructor, contains_ty};
+use rustc_hir::{Impl, ImplItem, ImplItemKind, ItemKind, Node};
+use rustc_lint::{LateContext, LateLintPass};
+use rustc_session::{declare_lint_pass, declare_tool_lint};
+
+declare_clippy_lint! {
+    /// **What it does:** Warns when constructors have the same name as their types.
+    ///
+    /// **Why is this bad?** Repeating the name of the type is redundant.
+    ///
+    /// **Known problems:** None.
+    ///
+    /// **Example:**
+    ///
+    /// ```rust,ignore
+    /// struct Foo {}
+    ///
+    /// impl Foo {
+    ///     pub fn foo() -> Foo {
+    ///         Foo {}
+    ///     }
+    /// }
+    /// ```
+    /// Use instead:
+    /// ```rust,ignore
+    /// struct Foo {}
+    ///
+    /// impl Foo {
+    ///     pub fn new() -> Foo {
+    ///         Foo {}
+    ///     }
+    /// }
+    /// ```
+    pub SELF_NAMED_CONSTRUCTOR,
+    style,
+    "method should not have the same name as the type it is implemented for"
+}
+
+declare_lint_pass!(SelfNamedConstructor => [SELF_NAMED_CONSTRUCTOR]);
+
+impl<'tcx> LateLintPass<'tcx> for SelfNamedConstructor {
+    fn check_impl_item(&mut self, cx: &LateContext<'tcx>, impl_item: &'tcx ImplItem<'_>) {
+        match impl_item.kind {
+            ImplItemKind::Fn(ref sig, _) => {
+                if sig.decl.implicit_self.has_implicit_self() {
+                    return;
+                }
+            },
+            _ => return,
+        }
+
+        let parent = cx.tcx.hir().get_parent_item(impl_item.hir_id());
+        let item = cx.tcx.hir().expect_item(parent);
+        let self_ty = cx.tcx.type_of(item.def_id);
+        let ret_ty = return_ty(cx, impl_item.hir_id());
+
+        // Do not check trait impls
+        if matches!(item.kind, ItemKind::Impl(Impl { of_trait: Some(_), .. })) {
+            return;
+        }
+
+        // Ensure method is constructor-like
+        if let Some(self_adt) = self_ty.ty_adt_def() {
+            if !contains_adt_constructor(ret_ty, self_adt) {
+                return;
+            }
+        } else if !contains_ty(ret_ty, self_ty) {
+            return;
+        }
+
+        if_chain! {
+            if let Some(self_def) = self_ty.ty_adt_def();
+            if let Some(self_local_did) = self_def.did.as_local();
+            let self_id = cx.tcx.hir().local_def_id_to_hir_id(self_local_did);
+            if let Some(Node::Item(x)) = cx.tcx.hir().find(self_id);
+            let type_name = x.ident.name.as_str().to_lowercase();
+            if impl_item.ident.name.as_str() == type_name || impl_item.ident.name.as_str().replace("_", "") == type_name;
+
+            then {
+                span_lint(
+                    cx,
+                    SELF_NAMED_CONSTRUCTOR,
+                    impl_item.span,
+                    &format!("constructor `{}` has the same name as the type", impl_item.ident.name),
+                );
+            }
+        }
+    }
+}
index 2203ab57b10820c626e99c0c0d1411b1d70004ca..f2bffd553210b1d5d0c531543a60a7b02b286bd9 100644 (file)
@@ -1,5 +1,5 @@
 use clippy_utils::diagnostics::span_lint;
-use clippy_utils::{get_trait_def_id, paths, trait_ref_of_method};
+use clippy_utils::{binop_traits, trait_ref_of_method, BINOP_TRAITS, OP_ASSIGN_TRAITS};
 use if_chain::if_chain;
 use rustc_hir as hir;
 use rustc_hir::intravisit::{walk_expr, NestedVisitorMap, Visitor};
 
 impl<'tcx> LateLintPass<'tcx> for SuspiciousImpl {
     fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>) {
-        if let hir::ExprKind::Binary(binop, _, _) | hir::ExprKind::AssignOp(binop, ..) = expr.kind {
-            match binop.node {
-                hir::BinOpKind::Eq
-                | hir::BinOpKind::Lt
-                | hir::BinOpKind::Le
-                | hir::BinOpKind::Ne
-                | hir::BinOpKind::Ge
-                | hir::BinOpKind::Gt => return,
-                _ => {},
-            }
+        if_chain! {
+            if let hir::ExprKind::Binary(binop, _, _) | hir::ExprKind::AssignOp(binop, ..) = expr.kind;
+            if let Some((binop_trait_lang, op_assign_trait_lang)) = binop_traits(binop.node);
+            if let Ok(binop_trait_id) = cx.tcx.lang_items().require(binop_trait_lang);
+            if let Ok(op_assign_trait_id) = cx.tcx.lang_items().require(op_assign_trait_lang);
 
             // Check for more than one binary operation in the implemented function
             // Linting when multiple operations are involved can result in false positives
             let parent_fn = cx.tcx.hir().get_parent_item(expr.hir_id);
-            if_chain! {
-                if let hir::Node::ImplItem(impl_item) = cx.tcx.hir().get(parent_fn);
-                if let hir::ImplItemKind::Fn(_, body_id) = impl_item.kind;
-                then {
-                    let body = cx.tcx.hir().body(body_id);
-                    let mut visitor = BinaryExprVisitor { nb_binops: 0 };
-                    walk_expr(&mut visitor, &body.value);
-                    if visitor.nb_binops > 1 {
-                        return;
-                    }
-                }
-            }
-
-            if let Some(impl_trait) = check_binop(
-                cx,
-                expr,
-                binop.node,
-                &[
-                    "Add", "Sub", "Mul", "Div", "Rem", "BitAnd", "BitOr", "BitXor", "Shl", "Shr",
-                ],
-                &[
-                    hir::BinOpKind::Add,
-                    hir::BinOpKind::Sub,
-                    hir::BinOpKind::Mul,
-                    hir::BinOpKind::Div,
-                    hir::BinOpKind::Rem,
-                    hir::BinOpKind::BitAnd,
-                    hir::BinOpKind::BitOr,
-                    hir::BinOpKind::BitXor,
-                    hir::BinOpKind::Shl,
-                    hir::BinOpKind::Shr,
-                ],
-            ) {
-                span_lint(
-                    cx,
-                    SUSPICIOUS_ARITHMETIC_IMPL,
-                    binop.span,
-                    &format!("suspicious use of binary operator in `{}` impl", impl_trait),
-                );
-            }
-
-            if let Some(impl_trait) = check_binop(
-                cx,
-                expr,
-                binop.node,
-                &[
-                    "AddAssign",
-                    "SubAssign",
-                    "MulAssign",
-                    "DivAssign",
-                    "BitAndAssign",
-                    "BitOrAssign",
-                    "BitXorAssign",
-                    "RemAssign",
-                    "ShlAssign",
-                    "ShrAssign",
-                ],
-                &[
-                    hir::BinOpKind::Add,
-                    hir::BinOpKind::Sub,
-                    hir::BinOpKind::Mul,
-                    hir::BinOpKind::Div,
-                    hir::BinOpKind::BitAnd,
-                    hir::BinOpKind::BitOr,
-                    hir::BinOpKind::BitXor,
-                    hir::BinOpKind::Rem,
-                    hir::BinOpKind::Shl,
-                    hir::BinOpKind::Shr,
-                ],
-            ) {
+            if let hir::Node::ImplItem(impl_item) = cx.tcx.hir().get(parent_fn);
+            if let hir::ImplItemKind::Fn(_, body_id) = impl_item.kind;
+            let body = cx.tcx.hir().body(body_id);
+            let parent_fn = cx.tcx.hir().get_parent_item(expr.hir_id);
+            if let Some(trait_ref) = trait_ref_of_method(cx, parent_fn);
+            let trait_id = trait_ref.path.res.def_id();
+            if ![binop_trait_id, op_assign_trait_id].contains(&trait_id);
+            if let Some(&(_, lint)) = [
+                (&BINOP_TRAITS, SUSPICIOUS_ARITHMETIC_IMPL),
+                (&OP_ASSIGN_TRAITS, SUSPICIOUS_OP_ASSIGN_IMPL),
+            ]
+                .iter()
+                .find(|&(ts, _)| ts.iter().any(|&t| Ok(trait_id) == cx.tcx.lang_items().require(t)));
+            if count_binops(&body.value) == 1;
+            then {
                 span_lint(
                     cx,
-                    SUSPICIOUS_OP_ASSIGN_IMPL,
+                    lint,
                     binop.span,
-                    &format!("suspicious use of binary operator in `{}` impl", impl_trait),
+                    &format!("suspicious use of `{}` in `{}` impl", binop.node.as_str(), cx.tcx.item_name(trait_id)),
                 );
             }
         }
     }
 }
 
-fn check_binop(
-    cx: &LateContext<'_>,
-    expr: &hir::Expr<'_>,
-    binop: hir::BinOpKind,
-    traits: &[&'static str],
-    expected_ops: &[hir::BinOpKind],
-) -> Option<&'static str> {
-    let mut trait_ids = vec![];
-    let [krate, module] = paths::OPS_MODULE;
-
-    for &t in traits {
-        let path = [krate, module, t];
-        if let Some(trait_id) = get_trait_def_id(cx, &path) {
-            trait_ids.push(trait_id);
-        } else {
-            return None;
-        }
-    }
-
-    // Get the actually implemented trait
-    let parent_fn = cx.tcx.hir().get_parent_item(expr.hir_id);
-
-    if_chain! {
-        if let Some(trait_ref) = trait_ref_of_method(cx, parent_fn);
-        if let Some(idx) = trait_ids.iter().position(|&tid| tid == trait_ref.path.res.def_id());
-        if binop != expected_ops[idx];
-        then{
-            return Some(traits[idx])
-        }
-    }
-
-    None
+fn count_binops(expr: &hir::Expr<'_>) -> u32 {
+    let mut visitor = BinaryExprVisitor::default();
+    visitor.visit_expr(expr);
+    visitor.nb_binops
 }
 
+#[derive(Default)]
 struct BinaryExprVisitor {
     nb_binops: u32,
 }
index f93f0047f514f5100536a77500a8a1082c48356b..053bbc9aea67433ddf6c83d1cecf141a319b946c 100644 (file)
@@ -4,7 +4,7 @@
 use if_chain::if_chain;
 use rustc_hir::{self as hir, HirId, ItemKind, Node};
 use rustc_lint::{LateContext, LateLintPass};
-use rustc_middle::ty::{Adt, Ty};
+use rustc_middle::ty::{Adt, Ty, TypeFoldable};
 use rustc_session::{declare_lint_pass, declare_tool_lint};
 use rustc_span::sym;
 use rustc_target::abi::LayoutOf as _;
@@ -52,6 +52,9 @@ fn check_ty(&mut self, cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>) {
             if is_type_diagnostic_item(cx, ty, sym::hashmap_type) || match_type(cx, ty, &paths::BTREEMAP);
             if let Adt(_, substs) = ty.kind();
             let ty = substs.type_at(1);
+            // Fixes https://github.com/rust-lang/rust-clippy/issues/7447 because of
+            // https://github.com/rust-lang/rust/blob/master/compiler/rustc_middle/src/ty/sty.rs#L968
+            if !ty.has_escaping_bound_vars();
             // Do this to prevent `layout_of` crashing, being unable to fully normalize `ty`.
             if is_normalizable(cx, cx.param_env, ty);
             if let Ok(layout) = cx.layout_of(ty);
index 3e3e472e99fb69215e7e07b2c70d34c4842674dd..f32f1109b08e64ec963dea3b653f120e816d0f0d 100644 (file)
 use rustc_lint::LateContext;
 use rustc_span::{sym, ExpnKind, Span, Symbol};
 
-/// Converts a hir binary operator to the corresponding `ast` type.
-#[must_use]
-pub fn binop(op: hir::BinOpKind) -> ast::BinOpKind {
-    match op {
-        hir::BinOpKind::Eq => ast::BinOpKind::Eq,
-        hir::BinOpKind::Ge => ast::BinOpKind::Ge,
-        hir::BinOpKind::Gt => ast::BinOpKind::Gt,
-        hir::BinOpKind::Le => ast::BinOpKind::Le,
-        hir::BinOpKind::Lt => ast::BinOpKind::Lt,
-        hir::BinOpKind::Ne => ast::BinOpKind::Ne,
-        hir::BinOpKind::Or => ast::BinOpKind::Or,
-        hir::BinOpKind::Add => ast::BinOpKind::Add,
-        hir::BinOpKind::And => ast::BinOpKind::And,
-        hir::BinOpKind::BitAnd => ast::BinOpKind::BitAnd,
-        hir::BinOpKind::BitOr => ast::BinOpKind::BitOr,
-        hir::BinOpKind::BitXor => ast::BinOpKind::BitXor,
-        hir::BinOpKind::Div => ast::BinOpKind::Div,
-        hir::BinOpKind::Mul => ast::BinOpKind::Mul,
-        hir::BinOpKind::Rem => ast::BinOpKind::Rem,
-        hir::BinOpKind::Shl => ast::BinOpKind::Shl,
-        hir::BinOpKind::Shr => ast::BinOpKind::Shr,
-        hir::BinOpKind::Sub => ast::BinOpKind::Sub,
-    }
-}
-
 /// Represent a range akin to `ast::ExprKind::Range`.
 #[derive(Debug, Copy, Clone)]
 pub struct Range<'a> {
index 4f0a9f442ed9f5b4893a67d135477aba49075c77..00db52a9457d85d50b30fb15da254764a55aa835 100644 (file)
@@ -909,12 +909,8 @@ pub fn is_integer_const(cx: &LateContext<'_>, e: &Expr<'_>, value: u128) -> bool
     if is_integer_literal(e, value) {
         return true;
     }
-    let map = cx.tcx.hir();
-    let parent_item = map.get_parent_item(e.hir_id);
-    if let Some((Constant::Int(v), _)) = map
-        .maybe_body_owned_by(parent_item)
-        .and_then(|body_id| constant(cx, cx.tcx.typeck_body(body_id), e))
-    {
+    let enclosing_body = cx.tcx.hir().local_def_id(cx.tcx.hir().enclosing_body_owner(e.hir_id));
+    if let Some((Constant::Int(v), _)) = constant(cx, cx.tcx.typeck(enclosing_body), e) {
         value == v
     } else {
         false
@@ -1041,18 +1037,14 @@ fn are_refutable<'a, I: IntoIterator<Item = &'a Pat<'a>>>(cx: &LateContext<'_>,
         PatKind::Struct(ref qpath, fields, _) => {
             is_enum_variant(cx, qpath, pat.hir_id) || are_refutable(cx, fields.iter().map(|field| &*field.pat))
         },
-        PatKind::TupleStruct(ref qpath, pats, _) => {
-            is_enum_variant(cx, qpath, pat.hir_id) || are_refutable(cx, pats)
-        },
+        PatKind::TupleStruct(ref qpath, pats, _) => is_enum_variant(cx, qpath, pat.hir_id) || are_refutable(cx, pats),
         PatKind::Slice(head, middle, tail) => {
             match &cx.typeck_results().node_type(pat.hir_id).kind() {
                 rustc_ty::Slice(..) => {
                     // [..] is the only irrefutable slice pattern.
                     !head.is_empty() || middle.is_none() || !tail.is_empty()
                 },
-                rustc_ty::Array(..) => {
-                    are_refutable(cx, head.iter().chain(middle).chain(tail.iter()))
-                },
+                rustc_ty::Array(..) => are_refutable(cx, head.iter().chain(middle).chain(tail.iter())),
                 _ => {
                     // unreachable!()
                     true
@@ -1710,3 +1702,34 @@ pub fn is_test_module_or_function(tcx: TyCtxt<'_>, item: &Item<'_>) -> bool {
 
     matches!(item.kind, ItemKind::Mod(..)) && item.ident.name.as_str().contains("test")
 }
+
+macro_rules! op_utils {
+    ($($name:ident $assign:ident)*) => {
+        /// Binary operation traits like `LangItem::Add`
+        pub static BINOP_TRAITS: &[LangItem] = &[$(LangItem::$name,)*];
+
+        /// Operator-Assign traits like `LangItem::AddAssign`
+        pub static OP_ASSIGN_TRAITS: &[LangItem] = &[$(LangItem::$assign,)*];
+
+        /// Converts `BinOpKind::Add` to `(LangItem::Add, LangItem::AddAssign)`, for example
+        pub fn binop_traits(kind: hir::BinOpKind) -> Option<(LangItem, LangItem)> {
+            match kind {
+                $(hir::BinOpKind::$name => Some((LangItem::$name, LangItem::$assign)),)*
+                _ => None,
+            }
+        }
+    };
+}
+
+op_utils! {
+    Add    AddAssign
+    Sub    SubAssign
+    Mul    MulAssign
+    Div    DivAssign
+    Rem    RemAssign
+    BitXor BitXorAssign
+    BitAnd BitAndAssign
+    BitOr  BitOrAssign
+    Shl    ShlAssign
+    Shr    ShrAssign
+}
index efc0ec50fdc947f9d209be2256d8c41ecf1f906b..3bd75b10e90588d45f47832a08e0ea6851737398 100644 (file)
@@ -154,7 +154,7 @@ fn hir_from_snippet(expr: &hir::Expr<'_>, snippet: Cow<'a, str>) -> Self {
             | hir::ExprKind::Err => Sugg::NonParen(snippet),
             hir::ExprKind::Assign(..) => Sugg::BinOp(AssocOp::Assign, snippet),
             hir::ExprKind::AssignOp(op, ..) => Sugg::BinOp(hirbinop2assignop(op), snippet),
-            hir::ExprKind::Binary(op, ..) => Sugg::BinOp(AssocOp::from_ast_binop(higher::binop(op.node)), snippet),
+            hir::ExprKind::Binary(op, ..) => Sugg::BinOp(AssocOp::from_ast_binop(op.node.into()), snippet),
             hir::ExprKind::Cast(..) => Sugg::BinOp(AssocOp::As, snippet),
             hir::ExprKind::Type(..) => Sugg::BinOp(AssocOp::Colon, snippet),
         }
index 3f5c5604d43f5e5b481cb370ad45739cf05e3942..523d55219ab6919fac1f8208c7fc739f8f98fc58 100644 (file)
@@ -257,10 +257,12 @@ pub fn is_type_diagnostic_item(cx: &LateContext<'_>, ty: Ty<'_>, diag_item: Symb
     }
 }
 
-/// Checks if the type is equal to a lang item
+/// Checks if the type is equal to a lang item.
+///
+/// Returns `false` if the `LangItem` is not defined.
 pub fn is_type_lang_item(cx: &LateContext<'_>, ty: Ty<'_>, lang_item: hir::LangItem) -> bool {
     match ty.kind() {
-        ty::Adt(adt, _) => cx.tcx.lang_items().require(lang_item).unwrap() == adt.did,
+        ty::Adt(adt, _) => cx.tcx.lang_items().require(lang_item).map_or(false, |li| li == adt.did),
         _ => false,
     }
 }
index e98354358af62a10c91ea9992426928b35131323..43d3792f5952125a80cb1eccb4b9d35213301a60 100644 (file)
@@ -14,6 +14,7 @@ the codebase take a look at [Adding Lints] or [Common Tools].
   - [lintcheck](#lintcheck)
   - [PR](#pr)
   - [Common Abbreviations](#common-abbreviations)
+  - [Install from source](#install-from-source)
 
 ## Get the Code
 
@@ -128,4 +129,45 @@ This is a concise list of abbreviations that can come up during Clippy developme
 general list can be found in the [rustc-dev-guide glossary][glossary]. Always feel free to ask if
 an abbreviation or meaning is unclear to you.
 
+## Install from source
+
+If you are hacking on Clippy and want to install it from source, do the following:
+
+First, take note of the toolchain [override](https://rust-lang.github.io/rustup/overrides.html) in `/rust-toolchain`.
+We will use this override to install Clippy into the right toolchain.
+
+> Tip: You can view the active toolchain for the current directory with `rustup show active-toolchain`.
+
+From the Clippy project root, run the following command to build the Clippy binaries and copy them into the
+toolchain directory. This will override the currently installed Clippy component.
+
+```terminal
+cargo build --release --bin cargo-clippy --bin clippy-driver -Zunstable-options --out-dir "$(rustc --print=sysroot)/bin"
+```
+
+Now you may run `cargo clippy` in any project, using the toolchain where you just installed Clippy.
+
+```terminal
+cd my-project
+cargo +nightly-2021-07-01 clippy
+```
+
+...or `clippy-driver`
+
+```terminal
+clippy-driver +nightly-2021-07-01 <filename>
+```
+
+If you need to restore the default Clippy installation, run the following (from the Clippy project root).
+
+```terminal
+rustup component remove clippy
+rustup component add clippy
+```
+
+> **DO NOT** install using `cargo install --path . --force` since this will overwrite rustup
+[proxies](https://rust-lang.github.io/rustup/concepts/proxies.html). That is, `~/.cargo/bin/cargo-clippy` and
+`~/.cargo/bin/clippy-driver` should be hard or soft links to `~/.cargo/bin/rustup`. You can repair these by running
+`rustup update`.
+
 [glossary]: https://rustc-dev-guide.rust-lang.org/appendix/glossary.html
index bf9cfb61b46d1a0e5d9895a91f50d36cb4699b5d..3a2005e787228e2b6ab961b7a4d977c3106b09bf 100644 (file)
@@ -1,3 +1,3 @@
 [toolchain]
-channel = "nightly-2021-07-15"
+channel = "nightly-2021-07-19"
 components = ["llvm-tools-preview", "rustc-dev", "rust-src"]
index f8c866a49aa20015be08faee7ade41ec0e49af06..8d9a1af8ff1180b50e824588b55bbcddc0cb93ea 100644 (file)
@@ -7,7 +7,7 @@
 struct Foo {}
 
 impl Foo {
-    fn foo() -> Self {
+    fn new() -> Self {
         impl Foo {
             fn bar() {}
         }
diff --git a/src/tools/clippy/tests/ui/crashes/ice-7340.rs b/src/tools/clippy/tests/ui/crashes/ice-7340.rs
new file mode 100644 (file)
index 0000000..7d2351d
--- /dev/null
@@ -0,0 +1,6 @@
+#![allow(clippy::no_effect)]
+
+fn main() {
+    const CONSTANT: usize = 8;
+    [1; 1 % CONSTANT];
+}
diff --git a/src/tools/clippy/tests/ui/crashes/ice-7410.rs b/src/tools/clippy/tests/ui/crashes/ice-7410.rs
new file mode 100644 (file)
index 0000000..aaa422d
--- /dev/null
@@ -0,0 +1,31 @@
+// compile-flags: -Clink-arg=-nostartfiles
+// ignore-macos
+// ignore-windows
+
+#![feature(lang_items, start, libc)]
+#![no_std]
+#![allow(clippy::redundant_pattern_matching)]
+
+use core::panic::PanicInfo;
+
+struct S;
+
+impl Drop for S {
+    fn drop(&mut self) {}
+}
+
+#[start]
+fn main(argc: isize, argv: *const *const u8) -> isize {
+    if let Some(_) = Some(S) {
+    } else {
+    }
+    0
+}
+
+#[panic_handler]
+fn panic(_info: &PanicInfo) -> ! {
+    loop {}
+}
+
+#[lang = "eh_personality"]
+extern "C" fn eh_personality() {}
diff --git a/src/tools/clippy/tests/ui/issue-7447.rs b/src/tools/clippy/tests/ui/issue-7447.rs
new file mode 100644 (file)
index 0000000..fdb77f3
--- /dev/null
@@ -0,0 +1,25 @@
+use std::{borrow::Cow, collections::BTreeMap, marker::PhantomData, sync::Arc};
+
+fn byte_view<'a>(s: &'a ByteView<'_>) -> BTreeMap<&'a str, ByteView<'a>> {
+    panic!()
+}
+
+fn group_entries(s: &()) -> BTreeMap<Cow<'_, str>, Vec<Cow<'_, str>>> {
+    todo!()
+}
+
+struct Mmap;
+
+enum ByteViewBacking<'a> {
+    Buf(Cow<'a, [u8]>),
+    Mmap(Mmap),
+}
+
+pub struct ByteView<'a> {
+    backing: Arc<ByteViewBacking<'a>>,
+}
+
+fn main() {
+    byte_view(panic!());
+    group_entries(panic!());
+}
index 8a9d5a3d1d5696afe426d685f3314916e020c067..cc699b79e433ca39756717f16714487a05421da7 100644 (file)
@@ -25,7 +25,9 @@ async fn all_to_one<'a>(a: &'a str, _b: &'a str) -> &'a str {
 struct Foo;
 impl Foo {
     // ok
-    pub async fn foo(&mut self) {}
+    pub async fn new(&mut self) -> Self {
+        Foo {}
+    }
 }
 
 // rust-lang/rust#61115
index bfa9ef01b0e9535e4f19fabe9ed0e8113b513695..d5724bf661c634ec89f3d83ac580a5c75facd6c6 100644 (file)
@@ -59,7 +59,9 @@ fn dummy(&self) {}
 }
 
 impl Foo {
-    pub fn foo() {}
+    pub fn new() -> Self {
+        Foo { a: 0, b: 0 }
+    }
     fn bar() {}
 }
 
index d33d512475b2389ec8bbd926ba28c132deb6a268..bda63d66a174af725e68b1f3b833cdb240e066e4 100644 (file)
@@ -78,23 +78,25 @@ LL |     type AssociatedTypeDef = Self;
 error: missing documentation for an associated function
   --> $DIR/missing-doc-impl.rs:62:5
    |
-LL |     pub fn foo() {}
-   |     ^^^^^^^^^^^^^^^
+LL | /     pub fn new() -> Self {
+LL | |         Foo { a: 0, b: 0 }
+LL | |     }
+   | |_____^
 
 error: missing documentation for an associated function
-  --> $DIR/missing-doc-impl.rs:63:5
+  --> $DIR/missing-doc-impl.rs:65:5
    |
 LL |     fn bar() {}
    |     ^^^^^^^^^^^
 
 error: missing documentation for an associated function
-  --> $DIR/missing-doc-impl.rs:67:5
+  --> $DIR/missing-doc-impl.rs:69:5
    |
 LL |     pub fn foo() {}
    |     ^^^^^^^^^^^^^^^
 
 error: missing documentation for an associated function
-  --> $DIR/missing-doc-impl.rs:71:5
+  --> $DIR/missing-doc-impl.rs:73:5
    |
 LL | /     fn foo2() -> u32 {
 LL | |         1
index 7cda1aaa3c22894def353f9e6223546a930ab2f5..6d2cbb6ad96fa865870159854b8e1d053d6f0b75 100644 (file)
@@ -84,7 +84,7 @@ fn drop(&mut self) {}
 
     impl A {
         // This can not be const because the type implements `Drop`.
-        pub fn a(self) -> B {
+        pub fn b(self) -> B {
             B
         }
     }
index 567dbc54100a64943337b9c02c390dd7801f7804..5917ffc3e12ea94efcc44ffbc7074ce0cbba7893 100644 (file)
@@ -6,7 +6,8 @@
     dead_code,
     clippy::no_effect,
     clippy::if_same_then_else,
-    clippy::needless_return
+    clippy::needless_return,
+    clippy::self_named_constructor
 )]
 
 use std::cell::Cell;
index 10126ad4dbb15aacd70053938e9e267dd42510ba..d26dcb9fcc33e8a0353a86b0000867f776cbef77 100644 (file)
@@ -6,7 +6,8 @@
     dead_code,
     clippy::no_effect,
     clippy::if_same_then_else,
-    clippy::needless_return
+    clippy::needless_return,
+    clippy::self_named_constructor
 )]
 
 use std::cell::Cell;
index 25abfb2a472b621130483c7eb5629ef7f946fab1..8026d643c44882c476a9d8a9cfd059aa4ab389e9 100644 (file)
@@ -1,5 +1,5 @@
 error: this if-then-else expression returns a bool literal
-  --> $DIR/fixable.rs:39:5
+  --> $DIR/fixable.rs:40:5
    |
 LL | /     if x {
 LL | |         true
@@ -11,7 +11,7 @@ LL | |     };
    = note: `-D clippy::needless-bool` implied by `-D warnings`
 
 error: this if-then-else expression returns a bool literal
-  --> $DIR/fixable.rs:44:5
+  --> $DIR/fixable.rs:45:5
    |
 LL | /     if x {
 LL | |         false
@@ -21,7 +21,7 @@ LL | |     };
    | |_____^ help: you can reduce it to: `!x`
 
 error: this if-then-else expression returns a bool literal
-  --> $DIR/fixable.rs:49:5
+  --> $DIR/fixable.rs:50:5
    |
 LL | /     if x && y {
 LL | |         false
@@ -31,7 +31,7 @@ LL | |     };
    | |_____^ help: you can reduce it to: `!(x && y)`
 
 error: this if-then-else expression returns a bool literal
-  --> $DIR/fixable.rs:69:5
+  --> $DIR/fixable.rs:70:5
    |
 LL | /     if x {
 LL | |         return true;
@@ -41,7 +41,7 @@ LL | |     };
    | |_____^ help: you can reduce it to: `return x`
 
 error: this if-then-else expression returns a bool literal
-  --> $DIR/fixable.rs:77:5
+  --> $DIR/fixable.rs:78:5
    |
 LL | /     if x {
 LL | |         return false;
@@ -51,7 +51,7 @@ LL | |     };
    | |_____^ help: you can reduce it to: `return !x`
 
 error: this if-then-else expression returns a bool literal
-  --> $DIR/fixable.rs:85:5
+  --> $DIR/fixable.rs:86:5
    |
 LL | /     if x && y {
 LL | |         return true;
@@ -61,7 +61,7 @@ LL | |     };
    | |_____^ help: you can reduce it to: `return x && y`
 
 error: this if-then-else expression returns a bool literal
-  --> $DIR/fixable.rs:93:5
+  --> $DIR/fixable.rs:94:5
    |
 LL | /     if x && y {
 LL | |         return false;
@@ -71,7 +71,7 @@ LL | |     };
    | |_____^ help: you can reduce it to: `return !(x && y)`
 
 error: equality checks against true are unnecessary
-  --> $DIR/fixable.rs:101:8
+  --> $DIR/fixable.rs:102:8
    |
 LL |     if x == true {};
    |        ^^^^^^^^^ help: try simplifying it as shown: `x`
@@ -79,25 +79,25 @@ LL |     if x == true {};
    = note: `-D clippy::bool-comparison` implied by `-D warnings`
 
 error: equality checks against false can be replaced by a negation
-  --> $DIR/fixable.rs:105:8
+  --> $DIR/fixable.rs:106:8
    |
 LL |     if x == false {};
    |        ^^^^^^^^^^ help: try simplifying it as shown: `!x`
 
 error: equality checks against true are unnecessary
-  --> $DIR/fixable.rs:115:8
+  --> $DIR/fixable.rs:116:8
    |
 LL |     if x == true {};
    |        ^^^^^^^^^ help: try simplifying it as shown: `x`
 
 error: equality checks against false can be replaced by a negation
-  --> $DIR/fixable.rs:116:8
+  --> $DIR/fixable.rs:117:8
    |
 LL |     if x == false {};
    |        ^^^^^^^^^^ help: try simplifying it as shown: `!x`
 
 error: this if-then-else expression returns a bool literal
-  --> $DIR/fixable.rs:125:12
+  --> $DIR/fixable.rs:126:12
    |
 LL |       } else if returns_bool() {
    |  ____________^
diff --git a/src/tools/clippy/tests/ui/self_named_constructor.rs b/src/tools/clippy/tests/ui/self_named_constructor.rs
new file mode 100644 (file)
index 0000000..7658b86
--- /dev/null
@@ -0,0 +1,59 @@
+#![warn(clippy::self_named_constructor)]
+
+struct ShouldSpawn;
+struct ShouldNotSpawn;
+
+impl ShouldSpawn {
+    pub fn should_spawn() -> ShouldSpawn {
+        ShouldSpawn
+    }
+
+    fn should_not_spawn() -> ShouldNotSpawn {
+        ShouldNotSpawn
+    }
+}
+
+impl ShouldNotSpawn {
+    pub fn new() -> ShouldNotSpawn {
+        ShouldNotSpawn
+    }
+}
+
+struct ShouldNotSpawnWithTrait;
+
+trait ShouldNotSpawnTrait {
+    type Item;
+}
+
+impl ShouldNotSpawnTrait for ShouldNotSpawnWithTrait {
+    type Item = Self;
+}
+
+impl ShouldNotSpawnWithTrait {
+    pub fn should_not_spawn_with_trait() -> impl ShouldNotSpawnTrait<Item = Self> {
+        ShouldNotSpawnWithTrait
+    }
+}
+
+// Same trait name and same type name should not spawn the lint
+#[derive(Default)]
+pub struct Default;
+
+trait TraitSameTypeName {
+    fn should_not_spawn() -> Self;
+}
+impl TraitSameTypeName for ShouldNotSpawn {
+    fn should_not_spawn() -> Self {
+        ShouldNotSpawn
+    }
+}
+
+struct SelfMethodShouldNotSpawn;
+
+impl SelfMethodShouldNotSpawn {
+    fn self_method_should_not_spawn(self) -> Self {
+        SelfMethodShouldNotSpawn
+    }
+}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui/self_named_constructor.stderr b/src/tools/clippy/tests/ui/self_named_constructor.stderr
new file mode 100644 (file)
index 0000000..1e2c34a
--- /dev/null
@@ -0,0 +1,12 @@
+error: constructor `should_spawn` has the same name as the type
+  --> $DIR/self_named_constructor.rs:7:5
+   |
+LL | /     pub fn should_spawn() -> ShouldSpawn {
+LL | |         ShouldSpawn
+LL | |     }
+   | |_____^
+   |
+   = note: `-D clippy::self-named-constructor` implied by `-D warnings`
+
+error: aborting due to previous error
+
index 63fc9ecb79a987923cc00f0cb5589e7b5020afa4..ced1305874e58611862db7bdccddc65428b911fa 100644 (file)
@@ -1,4 +1,4 @@
-error: suspicious use of binary operator in `Add` impl
+error: suspicious use of `-` in `Add` impl
   --> $DIR/suspicious_arithmetic_impl.rs:13:20
    |
 LL |         Foo(self.0 - other.0)
@@ -6,7 +6,7 @@ LL |         Foo(self.0 - other.0)
    |
    = note: `-D clippy::suspicious-arithmetic-impl` implied by `-D warnings`
 
-error: suspicious use of binary operator in `AddAssign` impl
+error: suspicious use of `-` in `AddAssign` impl
   --> $DIR/suspicious_arithmetic_impl.rs:19:23
    |
 LL |         *self = *self - other;
@@ -14,43 +14,43 @@ LL |         *self = *self - other;
    |
    = note: `-D clippy::suspicious-op-assign-impl` implied by `-D warnings`
 
-error: suspicious use of binary operator in `MulAssign` impl
+error: suspicious use of `/` in `MulAssign` impl
   --> $DIR/suspicious_arithmetic_impl.rs:32:16
    |
 LL |         self.0 /= other.0;
    |                ^^
 
-error: suspicious use of binary operator in `Rem` impl
+error: suspicious use of `/` in `Rem` impl
   --> $DIR/suspicious_arithmetic_impl.rs:70:20
    |
 LL |         Foo(self.0 / other.0)
    |                    ^
 
-error: suspicious use of binary operator in `BitAnd` impl
+error: suspicious use of `|` in `BitAnd` impl
   --> $DIR/suspicious_arithmetic_impl.rs:78:20
    |
 LL |         Foo(self.0 | other.0)
    |                    ^
 
-error: suspicious use of binary operator in `BitOr` impl
+error: suspicious use of `^` in `BitOr` impl
   --> $DIR/suspicious_arithmetic_impl.rs:86:20
    |
 LL |         Foo(self.0 ^ other.0)
    |                    ^
 
-error: suspicious use of binary operator in `BitXor` impl
+error: suspicious use of `&` in `BitXor` impl
   --> $DIR/suspicious_arithmetic_impl.rs:94:20
    |
 LL |         Foo(self.0 & other.0)
    |                    ^
 
-error: suspicious use of binary operator in `Shl` impl
+error: suspicious use of `>>` in `Shl` impl
   --> $DIR/suspicious_arithmetic_impl.rs:102:20
    |
 LL |         Foo(self.0 >> other.0)
    |                    ^^
 
-error: suspicious use of binary operator in `Shr` impl
+error: suspicious use of `<<` in `Shr` impl
   --> $DIR/suspicious_arithmetic_impl.rs:110:20
    |
 LL |         Foo(self.0 << other.0)
index 938cc3c785978f6b929bc6bd1d1d3eac799c32e6..df0fdaccb344a588981721eca88629d3348c6234 100644 (file)
@@ -6,7 +6,8 @@
     clippy::unused_unit,
     clippy::unnecessary_wraps,
     clippy::or_fun_call,
-    clippy::needless_question_mark
+    clippy::needless_question_mark,
+    clippy::self_named_constructor
 )]
 
 use std::fmt::Debug;
index 354fd51cd6b608954dd7e84888206744824cd4de..8155c4ae1107b23f57ac42a0439381850f975fdb 100644 (file)
@@ -1,5 +1,5 @@
 error: passing a unit value to a function
-  --> $DIR/unit_arg.rs:55:5
+  --> $DIR/unit_arg.rs:56:5
    |
 LL | /     foo({
 LL | |         1;
@@ -20,7 +20,7 @@ LL |     foo(());
    |
 
 error: passing a unit value to a function
-  --> $DIR/unit_arg.rs:58:5
+  --> $DIR/unit_arg.rs:59:5
    |
 LL |     foo(foo(1));
    |     ^^^^^^^^^^^
@@ -32,7 +32,7 @@ LL |     foo(());
    |
 
 error: passing a unit value to a function
-  --> $DIR/unit_arg.rs:59:5
+  --> $DIR/unit_arg.rs:60:5
    |
 LL | /     foo({
 LL | |         foo(1);
@@ -54,7 +54,7 @@ LL |     foo(());
    |
 
 error: passing a unit value to a function
-  --> $DIR/unit_arg.rs:64:5
+  --> $DIR/unit_arg.rs:65:5
    |
 LL | /     b.bar({
 LL | |         1;
@@ -74,7 +74,7 @@ LL |     b.bar(());
    |
 
 error: passing unit values to a function
-  --> $DIR/unit_arg.rs:67:5
+  --> $DIR/unit_arg.rs:68:5
    |
 LL |     taking_multiple_units(foo(0), foo(1));
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -87,7 +87,7 @@ LL |     taking_multiple_units((), ());
    |
 
 error: passing unit values to a function
-  --> $DIR/unit_arg.rs:68:5
+  --> $DIR/unit_arg.rs:69:5
    |
 LL | /     taking_multiple_units(foo(0), {
 LL | |         foo(1);
@@ -110,7 +110,7 @@ LL |     taking_multiple_units((), ());
    |
 
 error: passing unit values to a function
-  --> $DIR/unit_arg.rs:72:5
+  --> $DIR/unit_arg.rs:73:5
    |
 LL | /     taking_multiple_units(
 LL | |         {
@@ -140,7 +140,7 @@ LL |         foo(2);
  ...
 
 error: passing a unit value to a function
-  --> $DIR/unit_arg.rs:83:13
+  --> $DIR/unit_arg.rs:84:13
    |
 LL |     None.or(Some(foo(2)));
    |             ^^^^^^^^^^^^
@@ -154,7 +154,7 @@ LL |     });
    |
 
 error: passing a unit value to a function
-  --> $DIR/unit_arg.rs:86:5
+  --> $DIR/unit_arg.rs:87:5
    |
 LL |     foo(foo(()));
    |     ^^^^^^^^^^^^
@@ -166,7 +166,7 @@ LL |     foo(());
    |
 
 error: passing a unit value to a function
-  --> $DIR/unit_arg.rs:123:5
+  --> $DIR/unit_arg.rs:124:5
    |
 LL |     Some(foo(1))
    |     ^^^^^^^^^^^^
index e2c28542efc76e38c89aec06fc9bf7d670800dd6..23fc7632511c2e27449b1a442871e677e94eeacb 100644 (file)
@@ -4,7 +4,12 @@
 
 #![warn(clippy::use_self)]
 #![allow(dead_code)]
-#![allow(clippy::should_implement_trait, clippy::upper_case_acronyms, clippy::from_over_into)]
+#![allow(
+    clippy::should_implement_trait,
+    clippy::upper_case_acronyms,
+    clippy::from_over_into,
+    clippy::self_named_constructor
+)]
 
 #[macro_use]
 extern crate proc_macro_derive;
index 3cd99b9f5cd88775aaa07a061c5c8092fd852b96..bb46a33992371cd62e5e2cb5c75d0afdcf5c9941 100644 (file)
@@ -4,7 +4,12 @@
 
 #![warn(clippy::use_self)]
 #![allow(dead_code)]
-#![allow(clippy::should_implement_trait, clippy::upper_case_acronyms, clippy::from_over_into)]
+#![allow(
+    clippy::should_implement_trait,
+    clippy::upper_case_acronyms,
+    clippy::from_over_into,
+    clippy::self_named_constructor
+)]
 
 #[macro_use]
 extern crate proc_macro_derive;
index 6ac26c9e5a9cece3a876924c17595799c6efca9d..e14368a11aa746eddd1fffeeb88c3bc36c35982d 100644 (file)
@@ -1,5 +1,5 @@
 error: unnecessary structure name repetition
-  --> $DIR/use_self.rs:18:21
+  --> $DIR/use_self.rs:23:21
    |
 LL |         fn new() -> Foo {
    |                     ^^^ help: use the applicable keyword: `Self`
@@ -7,163 +7,163 @@ LL |         fn new() -> Foo {
    = note: `-D clippy::use-self` implied by `-D warnings`
 
 error: unnecessary structure name repetition
-  --> $DIR/use_self.rs:19:13
+  --> $DIR/use_self.rs:24:13
    |
 LL |             Foo {}
    |             ^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> $DIR/use_self.rs:21:22
+  --> $DIR/use_self.rs:26:22
    |
 LL |         fn test() -> Foo {
    |                      ^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> $DIR/use_self.rs:22:13
+  --> $DIR/use_self.rs:27:13
    |
 LL |             Foo::new()
    |             ^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> $DIR/use_self.rs:27:25
+  --> $DIR/use_self.rs:32:25
    |
 LL |         fn default() -> Foo {
    |                         ^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> $DIR/use_self.rs:28:13
+  --> $DIR/use_self.rs:33:13
    |
 LL |             Foo::new()
    |             ^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> $DIR/use_self.rs:93:24
+  --> $DIR/use_self.rs:98:24
    |
 LL |         fn bad(foos: &[Foo]) -> impl Iterator<Item = &Foo> {
    |                        ^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> $DIR/use_self.rs:93:55
+  --> $DIR/use_self.rs:98:55
    |
 LL |         fn bad(foos: &[Foo]) -> impl Iterator<Item = &Foo> {
    |                                                       ^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> $DIR/use_self.rs:108:13
+  --> $DIR/use_self.rs:113:13
    |
 LL |             TS(0)
    |             ^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> $DIR/use_self.rs:143:29
+  --> $DIR/use_self.rs:148:29
    |
 LL |                 fn bar() -> Bar {
    |                             ^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> $DIR/use_self.rs:144:21
+  --> $DIR/use_self.rs:149:21
    |
 LL |                     Bar { foo: Foo {} }
    |                     ^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> $DIR/use_self.rs:155:21
+  --> $DIR/use_self.rs:160:21
    |
 LL |         fn baz() -> Foo {
    |                     ^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> $DIR/use_self.rs:156:13
+  --> $DIR/use_self.rs:161:13
    |
 LL |             Foo {}
    |             ^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> $DIR/use_self.rs:173:21
+  --> $DIR/use_self.rs:178:21
    |
 LL |             let _ = Enum::B(42);
    |                     ^^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> $DIR/use_self.rs:174:21
+  --> $DIR/use_self.rs:179:21
    |
 LL |             let _ = Enum::C { field: true };
    |                     ^^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> $DIR/use_self.rs:175:21
+  --> $DIR/use_self.rs:180:21
    |
 LL |             let _ = Enum::A;
    |                     ^^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> $DIR/use_self.rs:217:13
+  --> $DIR/use_self.rs:222:13
    |
 LL |             nested::A::fun_1();
    |             ^^^^^^^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> $DIR/use_self.rs:218:13
+  --> $DIR/use_self.rs:223:13
    |
 LL |             nested::A::A;
    |             ^^^^^^^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> $DIR/use_self.rs:220:13
+  --> $DIR/use_self.rs:225:13
    |
 LL |             nested::A {};
    |             ^^^^^^^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> $DIR/use_self.rs:239:13
+  --> $DIR/use_self.rs:244:13
    |
 LL |             TestStruct::from_something()
    |             ^^^^^^^^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> $DIR/use_self.rs:253:25
+  --> $DIR/use_self.rs:258:25
    |
 LL |         async fn g() -> S {
    |                         ^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> $DIR/use_self.rs:254:13
+  --> $DIR/use_self.rs:259:13
    |
 LL |             S {}
    |             ^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> $DIR/use_self.rs:258:16
+  --> $DIR/use_self.rs:263:16
    |
 LL |             &p[S::A..S::B]
    |                ^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> $DIR/use_self.rs:258:22
+  --> $DIR/use_self.rs:263:22
    |
 LL |             &p[S::A..S::B]
    |                      ^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> $DIR/use_self.rs:281:29
+  --> $DIR/use_self.rs:286:29
    |
 LL |         fn foo(value: T) -> Foo<T> {
    |                             ^^^^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> $DIR/use_self.rs:282:13
+  --> $DIR/use_self.rs:287:13
    |
 LL |             Foo::<T> { value }
    |             ^^^^^^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> $DIR/use_self.rs:454:13
+  --> $DIR/use_self.rs:459:13
    |
 LL |             A::new::<submod::B>(submod::B {})
    |             ^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> $DIR/use_self.rs:491:13
+  --> $DIR/use_self.rs:496:13
    |
 LL |             S2::new()
    |             ^^ help: use the applicable keyword: `Self`
index 250eff85c86b089b77005691b899cea739f7e0cb..e2872a3f2a26154b91a6a6085d56016509803c61 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 250eff85c86b089b77005691b899cea739f7e0cb
+Subproject commit e2872a3f2a26154b91a6a6085d56016509803c61
index fe00358888a24c64878abc15f09b0e60e16db9d6..ea105f9396a9dab68e71efb06016b7c76c83ba7c 160000 (submodule)
@@ -1 +1 @@
-Subproject commit fe00358888a24c64878abc15f09b0e60e16db9d6
+Subproject commit ea105f9396a9dab68e71efb06016b7c76c83ba7c