From 910979a6d4a8e1945933cc989e6b22a675fc1d42 Mon Sep 17 00:00:00 2001 From: Takayuki Maeda <41065217+TaKO8Ki@users.noreply.github.com> Date: Tue, 17 May 2022 17:34:58 +0900 Subject: [PATCH 1/8] fix misleading `cannot infer type for type parameter` error --- .../infer/error_reporting/need_type_info.rs | 22 +++++++++++++++++++ .../ui/inference/ambiguous_type_parameter.rs | 17 ++++++++++++++ .../inference/ambiguous_type_parameter.stderr | 15 +++++++++++++ ...t-non-existing-fully-qualified-path.stderr | 5 +++++ 4 files changed, 59 insertions(+) create mode 100644 src/test/ui/inference/ambiguous_type_parameter.rs create mode 100644 src/test/ui/inference/ambiguous_type_parameter.stderr diff --git a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs index 62edfc6495cf6..5560230509069 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs @@ -866,6 +866,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } } + self.report_ambiguous_type_parameter(&mut err, arg); err.span_label( span, arg_data.cannot_infer_msg(use_diag.filter(|d| d.applies_to(span))), @@ -933,6 +934,27 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } } + fn report_ambiguous_type_parameter(&self, err: &mut Diagnostic, arg: GenericArg<'tcx>) { + if let GenericArgKind::Type(ty) = arg.unpack() + && let ty::Infer(ty::TyVar(ty_vid)) = *ty.kind() + { + let mut inner = self.inner.borrow_mut(); + let ty_vars = &inner.type_variables(); + let var_origin = ty_vars.var_origin(ty_vid); + if let TypeVariableOriginKind::TypeParameterDefinition(name, Some(def_id)) = + var_origin.kind + && let Some(parent_def_id) = self.tcx.parent(def_id).as_local() + && let Some(hir::Node::Item(item)) = self.tcx.hir().find_by_def_id(parent_def_id) + && let hir::ItemKind::Impl(impl_item) = item.kind + && let Some(trait_ref) = &impl_item.of_trait + && let Some(did) = trait_ref.trait_def_id() + && self.tcx.generics_of(did).params.iter().any(|param| param.name == name) + { + err.span_help(self.tcx.def_span(def_id), "type parameter declared here"); + } + } + } + pub fn need_type_info_err_in_generator( &self, kind: hir::GeneratorKind, diff --git a/src/test/ui/inference/ambiguous_type_parameter.rs b/src/test/ui/inference/ambiguous_type_parameter.rs new file mode 100644 index 0000000000000..dc70ed661d223 --- /dev/null +++ b/src/test/ui/inference/ambiguous_type_parameter.rs @@ -0,0 +1,17 @@ +use std::collections::HashMap; + +trait Store { + fn get_raw(&self, key: &K) -> Option<()>; +} + +struct InMemoryStore; + +impl Store> for InMemoryStore { + fn get_raw(&self, key: &String) -> Option<()> { + None + } +} + +fn main() { + InMemoryStore.get_raw(&String::default()); //~ ERROR type annotations needed +} diff --git a/src/test/ui/inference/ambiguous_type_parameter.stderr b/src/test/ui/inference/ambiguous_type_parameter.stderr new file mode 100644 index 0000000000000..47ef1948aee9f --- /dev/null +++ b/src/test/ui/inference/ambiguous_type_parameter.stderr @@ -0,0 +1,15 @@ +error[E0282]: type annotations needed + --> $DIR/ambiguous_type_parameter.rs:16:19 + | +LL | InMemoryStore.get_raw(&String::default()); + | ^^^^^^^ cannot infer type for type parameter `K` + | +help: type parameter declared here + --> $DIR/ambiguous_type_parameter.rs:9:6 + | +LL | impl Store> for InMemoryStore { + | ^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0282`. diff --git a/src/test/ui/traits/not-suggest-non-existing-fully-qualified-path.stderr b/src/test/ui/traits/not-suggest-non-existing-fully-qualified-path.stderr index 65f2d99417f2f..3c8d7450f96fa 100644 --- a/src/test/ui/traits/not-suggest-non-existing-fully-qualified-path.stderr +++ b/src/test/ui/traits/not-suggest-non-existing-fully-qualified-path.stderr @@ -16,6 +16,11 @@ LL | a.method(); | | cannot infer type for type parameter `U` | this method call resolves to `U` | +help: type parameter declared here + --> $DIR/not-suggest-non-existing-fully-qualified-path.rs:12:9 + | +LL | impl V for A + | ^ note: multiple `impl`s satisfying `B: I<_>` found --> $DIR/not-suggest-non-existing-fully-qualified-path.rs:5:1 | From 1a41a665cf4333696a44eacfa1d97180cc981185 Mon Sep 17 00:00:00 2001 From: ajtribick Date: Thu, 19 May 2022 20:54:16 +0200 Subject: [PATCH 2/8] Reverse condition in Vec::retain_mut doctest --- library/alloc/src/vec/mod.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index 3dc8a4fbba86b..62bc04cadeebc 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -1470,11 +1470,11 @@ impl Vec { /// /// ``` /// let mut vec = vec![1, 2, 3, 4]; - /// vec.retain_mut(|x| if *x > 3 { - /// false - /// } else { + /// vec.retain_mut(|x| if *x <= 3 { /// *x += 1; /// true + /// } else { + /// false /// }); /// assert_eq!(vec, [2, 3, 4]); /// ``` From 36ad596ef3006f67f2533cd4ac540c20c5e1f1d3 Mon Sep 17 00:00:00 2001 From: ydah <13041216+ydah@users.noreply.github.com> Date: Fri, 20 May 2022 10:39:10 +0900 Subject: [PATCH 3/8] Fix typo This PR is fixes typo "avaiable" to "available". --- src/doc/rustc/src/platform-support/pc-windows-gnullvm.md | 4 ++-- src/tools/rustfmt/tests/source/cfg_if/detect/arch/x86.rs | 2 +- src/tools/rustfmt/tests/target/cfg_if/detect/arch/x86.rs | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/doc/rustc/src/platform-support/pc-windows-gnullvm.md b/src/doc/rustc/src/platform-support/pc-windows-gnullvm.md index 96ae065b31b0b..721c234c6e60a 100644 --- a/src/doc/rustc/src/platform-support/pc-windows-gnullvm.md +++ b/src/doc/rustc/src/platform-support/pc-windows-gnullvm.md @@ -4,7 +4,7 @@ Windows targets similar to `*-pc-windows-gnu` but using UCRT as the runtime and various LLVM tools/libraries instead of GCC/Binutils. -Target triples avaiable so far: +Target triples available so far: - `aarch64-pc-windows-gnullvm` - `x86_64-pc-windows-gnullvm` @@ -26,7 +26,7 @@ Like with any other Windows target created binaries are in PE format. ## Building the target For cross-compilation I recommend using [llvm-mingw](https://github.com/mstorsjo/llvm-mingw) toolchain, one change that seems necessary beside configuring corss compilers is disabling experimental `m86k` target. Otherwise LLVM build fails with `multiple definition ...` errors. -Native bootstrapping builds require rather fragile hacks until host artifacts are avaiable so I won't describe them here. +Native bootstrapping builds require rather fragile hacks until host artifacts are available so I won't describe them here. ## Building Rust programs diff --git a/src/tools/rustfmt/tests/source/cfg_if/detect/arch/x86.rs b/src/tools/rustfmt/tests/source/cfg_if/detect/arch/x86.rs index 4c71a2c6ab90b..d26f4ee894fad 100644 --- a/src/tools/rustfmt/tests/source/cfg_if/detect/arch/x86.rs +++ b/src/tools/rustfmt/tests/source/cfg_if/detect/arch/x86.rs @@ -3,7 +3,7 @@ //! The features are detected using the `detect_features` function below. //! This function uses the CPUID instruction to read the feature flags from the //! CPU and encodes them in a `usize` where each bit position represents -//! whether a feature is available (bit is set) or unavaiable (bit is cleared). +//! whether a feature is available (bit is set) or unavailable (bit is cleared). //! //! The enum `Feature` is used to map bit positions to feature names, and the //! the `__crate::detect::check_for!` macro is used to map string literals (e.g., diff --git a/src/tools/rustfmt/tests/target/cfg_if/detect/arch/x86.rs b/src/tools/rustfmt/tests/target/cfg_if/detect/arch/x86.rs index b985dd8caa1ff..02d5eed1c2923 100644 --- a/src/tools/rustfmt/tests/target/cfg_if/detect/arch/x86.rs +++ b/src/tools/rustfmt/tests/target/cfg_if/detect/arch/x86.rs @@ -3,7 +3,7 @@ //! The features are detected using the `detect_features` function below. //! This function uses the CPUID instruction to read the feature flags from the //! CPU and encodes them in a `usize` where each bit position represents -//! whether a feature is available (bit is set) or unavaiable (bit is cleared). +//! whether a feature is available (bit is set) or unavailable (bit is cleared). //! //! The enum `Feature` is used to map bit positions to feature names, and the //! the `__crate::detect::check_for!` macro is used to map string literals (e.g., From 6eb41178c4d118692efe0e4928e0034f70235bf1 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Thu, 19 May 2022 19:06:01 -0700 Subject: [PATCH 4/8] Minor tweaks to rustc book summary formatting. --- src/doc/rustc/src/SUMMARY.md | 20 +++++++++---------- src/doc/rustc/src/codegen-options/index.md | 2 +- src/doc/rustc/src/command-line-arguments.md | 2 +- src/doc/rustc/src/instrument-coverage.md | 2 +- src/doc/rustc/src/linker-plugin-lto.md | 2 +- src/doc/rustc/src/lints/levels.md | 2 +- .../src/lints/listing/allowed-by-default.md | 2 +- .../src/lints/listing/deny-by-default.md | 2 +- src/doc/rustc/src/lints/listing/index.md | 2 +- .../src/lints/listing/warn-by-default.md | 2 +- .../rustc/src/profile-guided-optimization.md | 2 +- src/tools/lint-docs/src/lib.rs | 6 +++--- 12 files changed, 23 insertions(+), 23 deletions(-) diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md index c2d44ac0e4dce..7b2c35c0593d5 100644 --- a/src/doc/rustc/src/SUMMARY.md +++ b/src/doc/rustc/src/SUMMARY.md @@ -1,19 +1,20 @@ # The Rustc Book - [What is rustc?](what-is-rustc.md) -- [Command-line arguments](command-line-arguments.md) +- [Command-line Arguments](command-line-arguments.md) + - [Codegen Options](codegen-options/index.md) - [Lints](lints/index.md) - - [Lint levels](lints/levels.md) + - [Lint Levels](lints/levels.md) - [Lint Groups](lints/groups.md) - - [Lint listing](lints/listing/index.md) - - [Allowed-by-default lints](lints/listing/allowed-by-default.md) - - [Warn-by-default lints](lints/listing/warn-by-default.md) - - [Deny-by-default lints](lints/listing/deny-by-default.md) -- [Codegen options](codegen-options/index.md) + - [Lint Listing](lints/listing/index.md) + - [Allowed-by-default Lints](lints/listing/allowed-by-default.md) + - [Warn-by-default Lints](lints/listing/warn-by-default.md) + - [Deny-by-default Lints](lints/listing/deny-by-default.md) - [JSON Output](json.md) - [Tests](tests/index.md) - [Platform Support](platform-support.md) - - [Template for target-specific documentation](platform-support/TEMPLATE.md) + - [Target Tier Policy](target-tier-policy.md) + - [Template for Target-specific Documentation](platform-support/TEMPLATE.md) - [aarch64-apple-ios-sim](platform-support/aarch64-apple-ios-sim.md) - [armv7-unknown-linux-uclibceabi](platform-support/armv7-unknown-linux-uclibceabi.md) - [armv7-unknown-linux-uclibceabihf](platform-support/armv7-unknown-linux-uclibceabihf.md) @@ -25,13 +26,12 @@ - [*-unknown-openbsd](platform-support/openbsd.md) - [wasm64-unknown-unknown](platform-support/wasm64-unknown-unknown.md) - [x86_64-unknown-none](platform-support/x86_64-unknown-none.md) -- [Target Tier Policy](target-tier-policy.md) - [Targets](targets/index.md) - [Built-in Targets](targets/built-in.md) - [Custom Targets](targets/custom.md) - [Known Issues](targets/known-issues.md) - [Profile-guided Optimization](profile-guided-optimization.md) - [Instrumentation-based Code Coverage](instrument-coverage.md) -- [Linker-plugin based LTO](linker-plugin-lto.md) +- [Linker-plugin-based LTO](linker-plugin-lto.md) - [Exploit Mitigations](exploit-mitigations.md) - [Contributing to `rustc`](contributing.md) diff --git a/src/doc/rustc/src/codegen-options/index.md b/src/doc/rustc/src/codegen-options/index.md index 02011325d6878..b1c3b618cec02 100644 --- a/src/doc/rustc/src/codegen-options/index.md +++ b/src/doc/rustc/src/codegen-options/index.md @@ -1,4 +1,4 @@ -# Codegen options +# Codegen Options All of these options are passed to `rustc` via the `-C` flag, short for "codegen." You can see a version of this list for your exact compiler by running `rustc -C help`. diff --git a/src/doc/rustc/src/command-line-arguments.md b/src/doc/rustc/src/command-line-arguments.md index d80e4f2086995..73e7764a11d37 100644 --- a/src/doc/rustc/src/command-line-arguments.md +++ b/src/doc/rustc/src/command-line-arguments.md @@ -1,4 +1,4 @@ -# Command-line arguments +# Command-line Arguments Here's a list of command-line arguments to `rustc` and what they do. diff --git a/src/doc/rustc/src/instrument-coverage.md b/src/doc/rustc/src/instrument-coverage.md index 108b0ffe99b85..0ae9e53af3cd2 100644 --- a/src/doc/rustc/src/instrument-coverage.md +++ b/src/doc/rustc/src/instrument-coverage.md @@ -1,4 +1,4 @@ -# `instrument-coverage` +# Instrumentation-based Code Coverage ## Introduction diff --git a/src/doc/rustc/src/linker-plugin-lto.md b/src/doc/rustc/src/linker-plugin-lto.md index e7bf8d9a36f25..9c644dd404dc4 100644 --- a/src/doc/rustc/src/linker-plugin-lto.md +++ b/src/doc/rustc/src/linker-plugin-lto.md @@ -1,4 +1,4 @@ -# Linker-plugin-LTO +# Linker-plugin-based LTO The `-C linker-plugin-lto` flag allows for deferring the LTO optimization to the actual linking step, which in turn allows for performing diff --git a/src/doc/rustc/src/lints/levels.md b/src/doc/rustc/src/lints/levels.md index fbec3cd9baf50..93892d6ade61b 100644 --- a/src/doc/rustc/src/lints/levels.md +++ b/src/doc/rustc/src/lints/levels.md @@ -1,4 +1,4 @@ -# Lint levels +# Lint Levels In `rustc`, lints are divided into five *levels*: diff --git a/src/doc/rustc/src/lints/listing/allowed-by-default.md b/src/doc/rustc/src/lints/listing/allowed-by-default.md index 95dd60bebfbad..8c4c0b9c5581d 100644 --- a/src/doc/rustc/src/lints/listing/allowed-by-default.md +++ b/src/doc/rustc/src/lints/listing/allowed-by-default.md @@ -1,3 +1,3 @@ -# Allowed-by-default lints +# Allowed-by-default Lints This file is auto-generated by the lint-docs script. diff --git a/src/doc/rustc/src/lints/listing/deny-by-default.md b/src/doc/rustc/src/lints/listing/deny-by-default.md index 3c1452d64676c..12f511423b49a 100644 --- a/src/doc/rustc/src/lints/listing/deny-by-default.md +++ b/src/doc/rustc/src/lints/listing/deny-by-default.md @@ -1,3 +1,3 @@ -# Deny-by-default lints +# Deny-by-default Lints This file is auto-generated by the lint-docs script. diff --git a/src/doc/rustc/src/lints/listing/index.md b/src/doc/rustc/src/lints/listing/index.md index 97aa2caf91508..791a80274e205 100644 --- a/src/doc/rustc/src/lints/listing/index.md +++ b/src/doc/rustc/src/lints/listing/index.md @@ -1,4 +1,4 @@ -# Lint listing +# Lint Listing This section lists out all of the lints, grouped by their default lint levels. diff --git a/src/doc/rustc/src/lints/listing/warn-by-default.md b/src/doc/rustc/src/lints/listing/warn-by-default.md index eebc022a82bf8..84d67764f7d63 100644 --- a/src/doc/rustc/src/lints/listing/warn-by-default.md +++ b/src/doc/rustc/src/lints/listing/warn-by-default.md @@ -1,3 +1,3 @@ -# Warn-by-default lints +# Warn-by-default Lints This file is auto-generated by the lint-docs script. diff --git a/src/doc/rustc/src/profile-guided-optimization.md b/src/doc/rustc/src/profile-guided-optimization.md index d066f4a9cf59c..d9cf7ce30f936 100644 --- a/src/doc/rustc/src/profile-guided-optimization.md +++ b/src/doc/rustc/src/profile-guided-optimization.md @@ -1,4 +1,4 @@ -# Profile Guided Optimization +# Profile-guided Optimization `rustc` supports doing profile-guided optimization (PGO). This chapter describes what PGO is, what it is good for, and how it can be used. diff --git a/src/tools/lint-docs/src/lib.rs b/src/tools/lint-docs/src/lib.rs index fdc89a184da52..857feb7732536 100644 --- a/src/tools/lint-docs/src/lib.rs +++ b/src/tools/lint-docs/src/lib.rs @@ -482,20 +482,20 @@ fn lint_name(line: &str) -> Result { } } -static ALLOWED_MD: &str = r#"# Allowed-by-default lints +static ALLOWED_MD: &str = r#"# Allowed-by-default Lints These lints are all set to the 'allow' level by default. As such, they won't show up unless you set them to a higher lint level with a flag or attribute. "#; -static WARN_MD: &str = r#"# Warn-by-default lints +static WARN_MD: &str = r#"# Warn-by-default Lints These lints are all set to the 'warn' level by default. "#; -static DENY_MD: &str = r#"# Deny-by-default lints +static DENY_MD: &str = r#"# Deny-by-default Lints These lints are all set to the 'deny' level by default. From e7252739cdaf75d52dcdd6fb8abfa7d495e22a09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Le=C3=B3n=20Orell=20Valerian=20Liehr?= Date: Fri, 20 May 2022 10:19:23 +0200 Subject: [PATCH 5/8] Do not warn on inherent doc(hidden) assoc items --- compiler/rustc_passes/src/check_attr.rs | 2 +- .../ui/lint/unused/unused-attr-doc-hidden.fixed | 15 ++++++++++++++- src/test/ui/lint/unused/unused-attr-doc-hidden.rs | 15 ++++++++++++++- .../ui/lint/unused/unused-attr-doc-hidden.stderr | 14 +++++++------- 4 files changed, 36 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index ab3319a1186ae..3d5da114ecfde 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -832,7 +832,7 @@ impl CheckAttrVisitor<'_> { let parent_hir_id = self.tcx.hir().get_parent_item(hir_id); let containing_item = self.tcx.hir().expect_item(parent_hir_id); - if Target::from_item(containing_item) == Target::Impl { + if let hir::ItemKind::Impl(hir::Impl { of_trait: Some(_), .. }) = containing_item.kind { let meta_items = attr.meta_item_list().unwrap(); let (span, replacement_span) = if meta_items.len() == 1 { diff --git a/src/test/ui/lint/unused/unused-attr-doc-hidden.fixed b/src/test/ui/lint/unused/unused-attr-doc-hidden.fixed index 36a14097ac308..362ad55707a4a 100644 --- a/src/test/ui/lint/unused/unused-attr-doc-hidden.fixed +++ b/src/test/ui/lint/unused/unused-attr-doc-hidden.fixed @@ -1,5 +1,7 @@ -#![deny(unused_attributes)] +#![feature(inherent_associated_types)] +#![allow(dead_code, incomplete_features)] #![crate_type = "lib"] +#![deny(unused_attributes)] // run-rustfix pub trait Trait { @@ -12,6 +14,17 @@ pub trait Trait { pub struct Implementor; +impl Implementor { + #[doc(hidden)] // no error + type Inh = (); + + #[doc(hidden)] // no error + const INH: () = (); + + #[doc(hidden)] // no error + fn inh() {} +} + impl Trait for Implementor { type It = (); diff --git a/src/test/ui/lint/unused/unused-attr-doc-hidden.rs b/src/test/ui/lint/unused/unused-attr-doc-hidden.rs index e58c4f22f31ab..d493ed6dae206 100644 --- a/src/test/ui/lint/unused/unused-attr-doc-hidden.rs +++ b/src/test/ui/lint/unused/unused-attr-doc-hidden.rs @@ -1,5 +1,7 @@ -#![deny(unused_attributes)] +#![feature(inherent_associated_types)] +#![allow(dead_code, incomplete_features)] #![crate_type = "lib"] +#![deny(unused_attributes)] // run-rustfix pub trait Trait { @@ -12,6 +14,17 @@ pub trait Trait { pub struct Implementor; +impl Implementor { + #[doc(hidden)] // no error + type Inh = (); + + #[doc(hidden)] // no error + const INH: () = (); + + #[doc(hidden)] // no error + fn inh() {} +} + impl Trait for Implementor { #[doc(hidden)] type It = (); diff --git a/src/test/ui/lint/unused/unused-attr-doc-hidden.stderr b/src/test/ui/lint/unused/unused-attr-doc-hidden.stderr index fd1202a29de2e..f167bd460db3e 100644 --- a/src/test/ui/lint/unused/unused-attr-doc-hidden.stderr +++ b/src/test/ui/lint/unused/unused-attr-doc-hidden.stderr @@ -1,11 +1,11 @@ error: `#[doc(hidden)]` is ignored on trait impl items - --> $DIR/unused-attr-doc-hidden.rs:16:5 + --> $DIR/unused-attr-doc-hidden.rs:29:5 | LL | #[doc(hidden)] | ^^^^^^^^^^^^^^ help: remove this attribute | note: the lint level is defined here - --> $DIR/unused-attr-doc-hidden.rs:1:9 + --> $DIR/unused-attr-doc-hidden.rs:4:9 | LL | #![deny(unused_attributes)] | ^^^^^^^^^^^^^^^^^ @@ -13,7 +13,7 @@ LL | #![deny(unused_attributes)] = note: whether the impl item is `doc(hidden)` or not entirely depends on the corresponding trait item error: `#[doc(hidden)]` is ignored on trait impl items - --> $DIR/unused-attr-doc-hidden.rs:21:5 + --> $DIR/unused-attr-doc-hidden.rs:34:5 | LL | #[doc(hidden)] | ^^^^^^^^^^^^^^ help: remove this attribute @@ -22,7 +22,7 @@ LL | #[doc(hidden)] = note: whether the impl item is `doc(hidden)` or not entirely depends on the corresponding trait item error: `#[doc(hidden)]` is ignored on trait impl items - --> $DIR/unused-attr-doc-hidden.rs:26:11 + --> $DIR/unused-attr-doc-hidden.rs:39:11 | LL | #[doc(hidden, alias = "aka")] | ^^^^^^-- @@ -33,7 +33,7 @@ LL | #[doc(hidden, alias = "aka")] = note: whether the impl item is `doc(hidden)` or not entirely depends on the corresponding trait item error: `#[doc(hidden)]` is ignored on trait impl items - --> $DIR/unused-attr-doc-hidden.rs:31:27 + --> $DIR/unused-attr-doc-hidden.rs:44:27 | LL | #[doc(alias = "this", hidden,)] | ^^^^^^- @@ -44,7 +44,7 @@ LL | #[doc(alias = "this", hidden,)] = note: whether the impl item is `doc(hidden)` or not entirely depends on the corresponding trait item error: `#[doc(hidden)]` is ignored on trait impl items - --> $DIR/unused-attr-doc-hidden.rs:36:11 + --> $DIR/unused-attr-doc-hidden.rs:49:11 | LL | #[doc(hidden, hidden)] | ^^^^^^-- @@ -55,7 +55,7 @@ LL | #[doc(hidden, hidden)] = note: whether the impl item is `doc(hidden)` or not entirely depends on the corresponding trait item error: `#[doc(hidden)]` is ignored on trait impl items - --> $DIR/unused-attr-doc-hidden.rs:36:19 + --> $DIR/unused-attr-doc-hidden.rs:49:19 | LL | #[doc(hidden, hidden)] | ^^^^^^ help: remove this attribute From 3d0f9fb544cc73ea4016696e43868b71bf3c8226 Mon Sep 17 00:00:00 2001 From: Takayuki Maeda Date: Fri, 20 May 2022 13:49:41 +0900 Subject: [PATCH 6/8] report ambiguous type parameters when their parents are impl or fn fix ci error emit err for `impl_item` --- .../src/infer/error_reporting/need_type_info.rs | 13 +++++++------ .../ui/const-generics/issues/issue-83249.stderr | 6 ++++++ src/test/ui/consts/issue-64662.stderr | 12 ++++++++++++ src/test/ui/error-codes/E0401.stderr | 6 ++++++ .../ui/inference/erase-type-params-in-label.stderr | 10 ++++++++++ src/test/ui/inference/issue-86162-1.stderr | 5 +++++ src/test/ui/inference/issue-86162-2.stderr | 5 +++++ src/test/ui/issues/issue-6458.stderr | 6 ++++++ .../missing-items/missing-type-parameter.stderr | 6 ++++++ .../fn-needing-specified-return-type-param.stderr | 6 ++++++ .../traits/multidispatch-convert-ambig-dest.stderr | 11 +++++++++++ ...nbounded-type-param-in-fn-with-assoc-type.stderr | 6 ++++++ .../unbounded-type-param-in-fn.stderr | 6 ++++++ src/test/ui/type/type-annotation-needed.stderr | 5 +++++ 14 files changed, 97 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs index 5560230509069..e1a2a237c2324 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs @@ -941,15 +941,16 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { let mut inner = self.inner.borrow_mut(); let ty_vars = &inner.type_variables(); let var_origin = ty_vars.var_origin(ty_vid); - if let TypeVariableOriginKind::TypeParameterDefinition(name, Some(def_id)) = + if let TypeVariableOriginKind::TypeParameterDefinition(_, Some(def_id)) = var_origin.kind && let Some(parent_def_id) = self.tcx.parent(def_id).as_local() - && let Some(hir::Node::Item(item)) = self.tcx.hir().find_by_def_id(parent_def_id) - && let hir::ItemKind::Impl(impl_item) = item.kind - && let Some(trait_ref) = &impl_item.of_trait - && let Some(did) = trait_ref.trait_def_id() - && self.tcx.generics_of(did).params.iter().any(|param| param.name == name) + && let Some(node) = self.tcx.hir().find_by_def_id(parent_def_id) { + match node { + hir::Node::Item(item) if matches!(item.kind, hir::ItemKind::Impl(_) | hir::ItemKind::Fn(..)) => (), + hir::Node::ImplItem(impl_item) if matches!(impl_item.kind, hir::ImplItemKind::Fn(..)) => (), + _ => return, + } err.span_help(self.tcx.def_span(def_id), "type parameter declared here"); } } diff --git a/src/test/ui/const-generics/issues/issue-83249.stderr b/src/test/ui/const-generics/issues/issue-83249.stderr index 402b3aa2d61dc..3f44a54e80adc 100644 --- a/src/test/ui/const-generics/issues/issue-83249.stderr +++ b/src/test/ui/const-generics/issues/issue-83249.stderr @@ -5,6 +5,12 @@ LL | let _ = foo([0; 1]); | - ^^^ cannot infer type for type parameter `T` declared on the function `foo` | | | consider giving this pattern a type + | +help: type parameter declared here + --> $DIR/issue-83249.rs:12:8 + | +LL | fn foo(_: [u8; T::N]) -> T { + | ^ error: aborting due to previous error diff --git a/src/test/ui/consts/issue-64662.stderr b/src/test/ui/consts/issue-64662.stderr index dd281e911da96..caa582d87f527 100644 --- a/src/test/ui/consts/issue-64662.stderr +++ b/src/test/ui/consts/issue-64662.stderr @@ -3,12 +3,24 @@ error[E0282]: type annotations needed | LL | A = foo(), | ^^^ cannot infer type for type parameter `T` declared on the function `foo` + | +help: type parameter declared here + --> $DIR/issue-64662.rs:6:14 + | +LL | const fn foo() -> isize { + | ^ error[E0282]: type annotations needed --> $DIR/issue-64662.rs:3:9 | LL | B = foo(), | ^^^ cannot infer type for type parameter `T` declared on the function `foo` + | +help: type parameter declared here + --> $DIR/issue-64662.rs:6:14 + | +LL | const fn foo() -> isize { + | ^ error: aborting due to 2 previous errors diff --git a/src/test/ui/error-codes/E0401.stderr b/src/test/ui/error-codes/E0401.stderr index 8b1d4e6c07ceb..e58c9d3116a1c 100644 --- a/src/test/ui/error-codes/E0401.stderr +++ b/src/test/ui/error-codes/E0401.stderr @@ -37,6 +37,12 @@ error[E0282]: type annotations needed | LL | bfnr(x); | ^^^^ cannot infer type for type parameter `U` declared on the function `bfnr` + | +help: type parameter declared here + --> $DIR/E0401.rs:4:13 + | +LL | fn bfnr, W: Fn()>(y: T) { + | ^ error: aborting due to 4 previous errors diff --git a/src/test/ui/inference/erase-type-params-in-label.stderr b/src/test/ui/inference/erase-type-params-in-label.stderr index d0b06cde9d63a..51fac5f79df47 100644 --- a/src/test/ui/inference/erase-type-params-in-label.stderr +++ b/src/test/ui/inference/erase-type-params-in-label.stderr @@ -6,6 +6,11 @@ LL | let foo = foo(1, ""); | | | consider giving `foo` the explicit type `Foo<_, _, W, Z>`, where the type parameter `W` is specified | +help: type parameter declared here + --> $DIR/erase-type-params-in-label.rs:25:14 + | +LL | fn foo(t: T, k: K) -> Foo { + | ^ = note: cannot satisfy `_: Default` note: required by a bound in `foo` --> $DIR/erase-type-params-in-label.rs:25:17 @@ -25,6 +30,11 @@ LL | let bar = bar(1, ""); | | | consider giving `bar` the explicit type `Bar<_, _, Z>`, where the type parameter `Z` is specified | +help: type parameter declared here + --> $DIR/erase-type-params-in-label.rs:14:14 + | +LL | fn bar(t: T, k: K) -> Bar { + | ^ = note: cannot satisfy `_: Default` note: required by a bound in `bar` --> $DIR/erase-type-params-in-label.rs:14:17 diff --git a/src/test/ui/inference/issue-86162-1.stderr b/src/test/ui/inference/issue-86162-1.stderr index 8d6f50748cbeb..edf97c0aed47e 100644 --- a/src/test/ui/inference/issue-86162-1.stderr +++ b/src/test/ui/inference/issue-86162-1.stderr @@ -4,6 +4,11 @@ error[E0283]: type annotations needed LL | foo(gen()); //<- Do not suggest `foo::()`! | ^^^ cannot infer type for type parameter `impl Clone` declared on the function `foo` | +help: type parameter declared here + --> $DIR/issue-86162-1.rs:3:11 + | +LL | fn foo(x: impl Clone) {} + | ^^^^^^^^^^ = note: cannot satisfy `_: Clone` note: required by a bound in `foo` --> $DIR/issue-86162-1.rs:3:16 diff --git a/src/test/ui/inference/issue-86162-2.stderr b/src/test/ui/inference/issue-86162-2.stderr index 5f80c595628e4..c642ebb057603 100644 --- a/src/test/ui/inference/issue-86162-2.stderr +++ b/src/test/ui/inference/issue-86162-2.stderr @@ -4,6 +4,11 @@ error[E0283]: type annotations needed LL | Foo::bar(gen()); //<- Do not suggest `Foo::bar::()`! | ^^^^^^^^ cannot infer type for type parameter `impl Clone` declared on the associated function `bar` | +help: type parameter declared here + --> $DIR/issue-86162-2.rs:8:15 + | +LL | fn bar(x: impl Clone) {} + | ^^^^^^^^^^ = note: cannot satisfy `_: Clone` note: required by a bound in `Foo::bar` --> $DIR/issue-86162-2.rs:8:20 diff --git a/src/test/ui/issues/issue-6458.stderr b/src/test/ui/issues/issue-6458.stderr index f1a982616a4a1..f548692d78583 100644 --- a/src/test/ui/issues/issue-6458.stderr +++ b/src/test/ui/issues/issue-6458.stderr @@ -3,6 +3,12 @@ error[E0282]: type annotations needed | LL | foo(TypeWithState(marker::PhantomData)); | ^^^ cannot infer type for type parameter `State` declared on the function `foo` + | +help: type parameter declared here + --> $DIR/issue-6458.rs:6:12 + | +LL | pub fn foo(_: TypeWithState) {} + | ^^^^^ error: aborting due to previous error diff --git a/src/test/ui/missing/missing-items/missing-type-parameter.stderr b/src/test/ui/missing/missing-items/missing-type-parameter.stderr index 1219badc5b3fc..2aa2b0e6a3c2c 100644 --- a/src/test/ui/missing/missing-items/missing-type-parameter.stderr +++ b/src/test/ui/missing/missing-items/missing-type-parameter.stderr @@ -3,6 +3,12 @@ error[E0282]: type annotations needed | LL | foo(); | ^^^ cannot infer type for type parameter `X` declared on the function `foo` + | +help: type parameter declared here + --> $DIR/missing-type-parameter.rs:1:8 + | +LL | fn foo() { } + | ^ error: aborting due to previous error diff --git a/src/test/ui/suggestions/fn-needing-specified-return-type-param.stderr b/src/test/ui/suggestions/fn-needing-specified-return-type-param.stderr index b59a3818e7042..a4cfee5563373 100644 --- a/src/test/ui/suggestions/fn-needing-specified-return-type-param.stderr +++ b/src/test/ui/suggestions/fn-needing-specified-return-type-param.stderr @@ -5,6 +5,12 @@ LL | let _ = f; | - ^ cannot infer type for type parameter `A` declared on the function `f` | | | consider giving this pattern the explicit type `fn() -> A`, where the type parameter `A` is specified + | +help: type parameter declared here + --> $DIR/fn-needing-specified-return-type-param.rs:1:6 + | +LL | fn f() -> A { unimplemented!() } + | ^ error: aborting due to previous error diff --git a/src/test/ui/traits/multidispatch-convert-ambig-dest.stderr b/src/test/ui/traits/multidispatch-convert-ambig-dest.stderr index 9fd81b56bf153..da7461347106f 100644 --- a/src/test/ui/traits/multidispatch-convert-ambig-dest.stderr +++ b/src/test/ui/traits/multidispatch-convert-ambig-dest.stderr @@ -3,6 +3,12 @@ error[E0282]: type annotations needed | LL | test(22, std::default::Default::default()); | ^^^^ cannot infer type for type parameter `U` declared on the function `test` + | +help: type parameter declared here + --> $DIR/multidispatch-convert-ambig-dest.rs:20:11 + | +LL | fn test(_: T, _: U) + | ^ error[E0283]: type annotations needed --> $DIR/multidispatch-convert-ambig-dest.rs:26:5 @@ -10,6 +16,11 @@ error[E0283]: type annotations needed LL | test(22, std::default::Default::default()); | ^^^^ cannot infer type for type parameter `U` declared on the function `test` | +help: type parameter declared here + --> $DIR/multidispatch-convert-ambig-dest.rs:20:11 + | +LL | fn test(_: T, _: U) + | ^ note: multiple `impl`s satisfying `i32: Convert<_>` found --> $DIR/multidispatch-convert-ambig-dest.rs:8:1 | diff --git a/src/test/ui/type-inference/unbounded-type-param-in-fn-with-assoc-type.stderr b/src/test/ui/type-inference/unbounded-type-param-in-fn-with-assoc-type.stderr index d60ca4a49325c..501fa7c8c67c1 100644 --- a/src/test/ui/type-inference/unbounded-type-param-in-fn-with-assoc-type.stderr +++ b/src/test/ui/type-inference/unbounded-type-param-in-fn-with-assoc-type.stderr @@ -3,6 +3,12 @@ error[E0282]: type annotations needed | LL | foo(); | ^^^ cannot infer type for type parameter `T` declared on the function `foo` + | +help: type parameter declared here + --> $DIR/unbounded-type-param-in-fn-with-assoc-type.rs:3:8 + | +LL | fn foo() -> (T, U) { + | ^ error: aborting due to previous error diff --git a/src/test/ui/type-inference/unbounded-type-param-in-fn.stderr b/src/test/ui/type-inference/unbounded-type-param-in-fn.stderr index 45d879d8d5670..d01c3a7d4e220 100644 --- a/src/test/ui/type-inference/unbounded-type-param-in-fn.stderr +++ b/src/test/ui/type-inference/unbounded-type-param-in-fn.stderr @@ -3,6 +3,12 @@ error[E0282]: type annotations needed | LL | foo(); | ^^^ cannot infer type for type parameter `T` declared on the function `foo` + | +help: type parameter declared here + --> $DIR/unbounded-type-param-in-fn.rs:1:8 + | +LL | fn foo() -> T { + | ^ error: aborting due to previous error diff --git a/src/test/ui/type/type-annotation-needed.stderr b/src/test/ui/type/type-annotation-needed.stderr index f7dfb84523802..64fdbfe7db4c8 100644 --- a/src/test/ui/type/type-annotation-needed.stderr +++ b/src/test/ui/type/type-annotation-needed.stderr @@ -4,6 +4,11 @@ error[E0283]: type annotations needed LL | foo(42); | ^^^ cannot infer type for type parameter `T` declared on the function `foo` | +help: type parameter declared here + --> $DIR/type-annotation-needed.rs:1:8 + | +LL | fn foo>(x: i32) {} + | ^ = note: cannot satisfy `_: Into` note: required by a bound in `foo` --> $DIR/type-annotation-needed.rs:1:11 From de97d7393fd20215cdc1a2cacfa84290df4ae460 Mon Sep 17 00:00:00 2001 From: AngelicosPhosphoros Date: Fri, 20 May 2022 15:38:04 +0300 Subject: [PATCH 7/8] Add complexity estimation of iterating over HashSet and HashMap It is not obvious (at least for me) that complexity of iteration over hash tables depends on capacity and not length. Especially comparing with other containers like Vec or String. I think, this behaviour is worth mentioning. I run benchmark which tests iteration time for maps with length 50 and different capacities and get this results: ``` capacity - time 64 - 203.87 ns 256 - 351.78 ns 1024 - 607.87 ns 4096 - 965.82 ns 16384 - 3.1188 us ``` If you want to dig why it behaves such way, you can look current implementation in [hashbrown code](https://github.com/rust-lang/hashbrown/blob/f3a9f211d06f78c5beb81ac22ea08fdc269e068f/src/raw/mod.rs#L1933). Benchmarks code would be presented in PR related to this commit. --- library/std/src/collections/hash/map.rs | 40 +++++++++++++++++++++++++ library/std/src/collections/hash/set.rs | 10 +++++++ 2 files changed, 50 insertions(+) diff --git a/library/std/src/collections/hash/map.rs b/library/std/src/collections/hash/map.rs index 977714281fbbe..969f5dde4f05d 100644 --- a/library/std/src/collections/hash/map.rs +++ b/library/std/src/collections/hash/map.rs @@ -344,6 +344,11 @@ impl HashMap { /// println!("{key}"); /// } /// ``` + /// + /// # Performance + /// + /// In the current implementation, iterating over keys takes O(capacity) time + /// instead of O(len) because it internally visits empty buckets too. #[stable(feature = "rust1", since = "1.0.0")] pub fn keys(&self) -> Keys<'_, K, V> { Keys { inner: self.iter() } @@ -370,6 +375,11 @@ impl HashMap { /// vec.sort_unstable(); /// assert_eq!(vec, ["a", "b", "c"]); /// ``` + /// + /// # Performance + /// + /// In the current implementation, iterating over keys takes O(capacity) time + /// instead of O(len) because it internally visits empty buckets too. #[inline] #[rustc_lint_query_instability] #[stable(feature = "map_into_keys_values", since = "1.54.0")] @@ -395,6 +405,11 @@ impl HashMap { /// println!("{val}"); /// } /// ``` + /// + /// # Performance + /// + /// In the current implementation, iterating over values takes O(capacity) time + /// instead of O(len) because it internally visits empty buckets too. #[stable(feature = "rust1", since = "1.0.0")] pub fn values(&self) -> Values<'_, K, V> { Values { inner: self.iter() } @@ -422,6 +437,11 @@ impl HashMap { /// println!("{val}"); /// } /// ``` + /// + /// # Performance + /// + /// In the current implementation, iterating over values takes O(capacity) time + /// instead of O(len) because it internally visits empty buckets too. #[stable(feature = "map_values_mut", since = "1.10.0")] pub fn values_mut(&mut self) -> ValuesMut<'_, K, V> { ValuesMut { inner: self.iter_mut() } @@ -448,6 +468,11 @@ impl HashMap { /// vec.sort_unstable(); /// assert_eq!(vec, [1, 2, 3]); /// ``` + /// + /// # Performance + /// + /// In the current implementation, iterating over values takes O(capacity) time + /// instead of O(len) because it internally visits empty buckets too. #[inline] #[rustc_lint_query_instability] #[stable(feature = "map_into_keys_values", since = "1.54.0")] @@ -473,6 +498,11 @@ impl HashMap { /// println!("key: {key} val: {val}"); /// } /// ``` + /// + /// # Performance + /// + /// In the current implementation, iterating over map takes O(capacity) time + /// instead of O(len) because it internally visits empty buckets too. #[rustc_lint_query_instability] #[stable(feature = "rust1", since = "1.0.0")] pub fn iter(&self) -> Iter<'_, K, V> { @@ -503,6 +533,11 @@ impl HashMap { /// println!("key: {key} val: {val}"); /// } /// ``` + /// + /// # Performance + /// + /// In the current implementation, iterating over map takes O(capacity) time + /// instead of O(len) because it internally visits empty buckets too. #[rustc_lint_query_instability] #[stable(feature = "rust1", since = "1.0.0")] pub fn iter_mut(&mut self) -> IterMut<'_, K, V> { @@ -633,6 +668,11 @@ impl HashMap { /// map.retain(|&k, _| k % 2 == 0); /// assert_eq!(map.len(), 4); /// ``` + /// + /// # Performance + /// + /// In the current implementation, this operation takes O(capacity) time + /// instead of O(len) because it internally visits empty buckets too. #[inline] #[rustc_lint_query_instability] #[stable(feature = "retain_hash_collection", since = "1.18.0")] diff --git a/library/std/src/collections/hash/set.rs b/library/std/src/collections/hash/set.rs index 13bba0a6fd892..4ac0e081c2e2d 100644 --- a/library/std/src/collections/hash/set.rs +++ b/library/std/src/collections/hash/set.rs @@ -184,6 +184,11 @@ impl HashSet { /// println!("{x}"); /// } /// ``` + /// + /// # Performance + /// + /// In the current implementation, iterating over set takes O(capacity) time + /// instead of O(len) because it internally visits empty buckets too. #[inline] #[rustc_lint_query_instability] #[stable(feature = "rust1", since = "1.0.0")] @@ -312,6 +317,11 @@ impl HashSet { /// set.retain(|&k| k % 2 == 0); /// assert_eq!(set.len(), 3); /// ``` + /// + /// # Performance + /// + /// In the current implementation, this operation takes O(capacity) time + /// instead of O(len) because it internally visits empty buckets too. #[rustc_lint_query_instability] #[stable(feature = "retain_hash_collection", since = "1.18.0")] pub fn retain(&mut self, f: F) From eab9240627790407d5b443cebdfc77bafff4bb92 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Sat, 21 May 2022 01:32:02 +0900 Subject: [PATCH 8/8] Add regression test for #81827 --- src/test/ui/parser/issue-81827.rs | 11 +++++++++ src/test/ui/parser/issue-81827.stderr | 35 +++++++++++++++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 src/test/ui/parser/issue-81827.rs create mode 100644 src/test/ui/parser/issue-81827.stderr diff --git a/src/test/ui/parser/issue-81827.rs b/src/test/ui/parser/issue-81827.rs new file mode 100644 index 0000000000000..7ec5815941323 --- /dev/null +++ b/src/test/ui/parser/issue-81827.rs @@ -0,0 +1,11 @@ +// error-pattern: this file contains an unclosed delimiter +// error-pattern: mismatched closing delimiter: `]` +// error-pattern: expected one of `)` or `,`, found `{` + +#![crate_name="0"] + + + +fn main() {} + +fn r()->i{0|{#[cfg(r(0{]0 diff --git a/src/test/ui/parser/issue-81827.stderr b/src/test/ui/parser/issue-81827.stderr new file mode 100644 index 0000000000000..069de33919494 --- /dev/null +++ b/src/test/ui/parser/issue-81827.stderr @@ -0,0 +1,35 @@ +error: this file contains an unclosed delimiter + --> $DIR/issue-81827.rs:11:27 + | +LL | fn r()->i{0|{#[cfg(r(0{]0 + | - - ^ + | | | + | | unclosed delimiter + | unclosed delimiter + +error: this file contains an unclosed delimiter + --> $DIR/issue-81827.rs:11:27 + | +LL | fn r()->i{0|{#[cfg(r(0{]0 + | - - ^ + | | | + | | unclosed delimiter + | unclosed delimiter + +error: mismatched closing delimiter: `]` + --> $DIR/issue-81827.rs:11:23 + | +LL | fn r()->i{0|{#[cfg(r(0{]0 + | - ^^ mismatched closing delimiter + | | | + | | unclosed delimiter + | closing delimiter possibly meant for this + +error: expected one of `)` or `,`, found `{` + --> $DIR/issue-81827.rs:11:23 + | +LL | fn r()->i{0|{#[cfg(r(0{]0 + | ^ expected one of `)` or `,` + +error: aborting due to 4 previous errors +