From 18b86468b8c47bb3d4a6b6d1068947cae5cb7c1d Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 16 Jun 2023 14:56:31 +0200 Subject: [PATCH 01/24] slice::from_raw_parts: mention no-wrap-around condition --- library/core/src/slice/raw.rs | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/library/core/src/slice/raw.rs b/library/core/src/slice/raw.rs index 052fd34d0b6b7..48a6eb03b5e1c 100644 --- a/library/core/src/slice/raw.rs +++ b/library/core/src/slice/raw.rs @@ -32,7 +32,8 @@ use crate::ptr; /// * The memory referenced by the returned slice must not be mutated for the duration /// of lifetime `'a`, except inside an `UnsafeCell`. /// -/// * The total size `len * mem::size_of::()` of the slice must be no larger than `isize::MAX`. +/// * The total size `len * mem::size_of::()` of the slice must be no larger than `isize::MAX`, +/// and adding that size to `data` must not "wrap around" the address space. /// See the safety documentation of [`pointer::offset`]. /// /// # Caveat @@ -125,7 +126,8 @@ pub const unsafe fn from_raw_parts<'a, T>(data: *const T, len: usize) -> &'a [T] /// (not derived from the return value) for the duration of lifetime `'a`. /// Both read and write accesses are forbidden. /// -/// * The total size `len * mem::size_of::()` of the slice must be no larger than `isize::MAX`. +/// * The total size `len * mem::size_of::()` of the slice must be no larger than `isize::MAX`, +/// and adding that size to `data` must not "wrap around" the address space. /// See the safety documentation of [`pointer::offset`]. /// /// [valid]: ptr#safety @@ -179,15 +181,16 @@ pub const fn from_mut(s: &mut T) -> &mut [T] { /// the last element, such that the offset from the end to the start pointer is /// the length of the slice. /// -/// * The range must contain `N` consecutive properly initialized values of type `T`: +/// * The entire memory range of this slice must be contained within a single allocated object! +/// Slices can never span across multiple allocated objects. /// -/// * The entire memory range of this slice must be contained within a single allocated object! -/// Slices can never span across multiple allocated objects. +/// * The range must contain `N` consecutive properly initialized values of type `T`. /// /// * The memory referenced by the returned slice must not be mutated for the duration /// of lifetime `'a`, except inside an `UnsafeCell`. /// -/// * The total length of the range must be no larger than `isize::MAX`. +/// * The total length of the range must be no larger than `isize::MAX`, +/// and adding that size to `data` must not "wrap around" the address space. /// See the safety documentation of [`pointer::offset`]. /// /// Note that a range created from [`slice::as_ptr_range`] fulfills these requirements. @@ -247,16 +250,17 @@ pub const unsafe fn from_ptr_range<'a, T>(range: Range<*const T>) -> &'a [T] { /// the last element, such that the offset from the end to the start pointer is /// the length of the slice. /// -/// * The range must contain `N` consecutive properly initialized values of type `T`: +/// * The entire memory range of this slice must be contained within a single allocated object! +/// Slices can never span across multiple allocated objects. /// -/// * The entire memory range of this slice must be contained within a single allocated object! -/// Slices can never span across multiple allocated objects. +/// * The range must contain `N` consecutive properly initialized values of type `T`. /// /// * The memory referenced by the returned slice must not be accessed through any other pointer /// (not derived from the return value) for the duration of lifetime `'a`. /// Both read and write accesses are forbidden. /// -/// * The total length of the range must be no larger than `isize::MAX`. +/// * The total length of the range must be no larger than `isize::MAX`, +/// and adding that size to `data` must not "wrap around" the address space. /// See the safety documentation of [`pointer::offset`]. /// /// Note that a range created from [`slice::as_mut_ptr_range`] fulfills these requirements. From 9202caaec536bf299f055f4915369aafda5e742e Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 22 Jun 2023 17:38:19 +0200 Subject: [PATCH 02/24] Fix indentation for where clause in rustdoc pages --- src/librustdoc/html/format.rs | 17 ++++++++++++----- src/librustdoc/html/render/mod.rs | 4 ++-- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index f26d74629dd94..b710311c85872 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -347,13 +347,19 @@ pub(crate) fn print_where_clause<'a, 'tcx: 'a>( } } else { let mut br_with_padding = String::with_capacity(6 * indent + 28); - br_with_padding.push_str("\n"); + br_with_padding.push('\n'); - let padding_amount = - if ending == Ending::Newline { indent + 4 } else { indent + "fn where ".len() }; + let where_indent = 3; + let padding_amount = if ending == Ending::Newline { + indent + 4 + } else if indent == 0 { + 4 + } else { + indent + where_indent + "where ".len() + }; for _ in 0..padding_amount { - br_with_padding.push_str(" "); + br_with_padding.push(' '); } let where_preds = where_preds.to_string().replace('\n', &br_with_padding); @@ -370,7 +376,8 @@ pub(crate) fn print_where_clause<'a, 'tcx: 'a>( let where_preds = where_preds.replacen(&br_with_padding, " ", 1); let mut clause = br_with_padding; - clause.truncate(clause.len() - "where ".len()); + // +1 is for `\n`. + clause.truncate(indent + 1 + where_indent); write!(clause, "where{where_preds}")?; clause diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index c5d6771c2fdd3..0199364151d45 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -859,8 +859,8 @@ fn assoc_method( w.reserve(header_len + "{".len() + "".len()); write!( w, - "{indent}{vis}{constness}{asyncness}{unsafety}{defaultness}{abi}fn {name}\ - {generics}{decl}{notable_traits}{where_clause}", + "{indent}{vis}{constness}{asyncness}{unsafety}{defaultness}{abi}fn \ + {name}{generics}{decl}{notable_traits}{where_clause}", indent = indent_str, vis = vis, constness = constness, From b858a4745caacc1bab3e2d50f38add451030941f Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 22 Jun 2023 17:39:23 +0200 Subject: [PATCH 03/24] Update existing snapshot and add more snapshots of where clause indentation --- tests/rustdoc/where.SWhere_Echo_impl.html | 2 ++ tests/rustdoc/where.SWhere_Simd_item-decl.html | 2 +- tests/rustdoc/where.alpha_trait_decl.html | 3 +++ tests/rustdoc/where.bravo_trait_decl.html | 5 +++++ tests/rustdoc/where.charlie_fn_decl.html | 2 ++ tests/rustdoc/where.golf_type_alias_decl.html | 2 ++ tests/rustdoc/where.rs | 5 +++++ 7 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 tests/rustdoc/where.SWhere_Echo_impl.html create mode 100644 tests/rustdoc/where.alpha_trait_decl.html create mode 100644 tests/rustdoc/where.bravo_trait_decl.html create mode 100644 tests/rustdoc/where.charlie_fn_decl.html create mode 100644 tests/rustdoc/where.golf_type_alias_decl.html diff --git a/tests/rustdoc/where.SWhere_Echo_impl.html b/tests/rustdoc/where.SWhere_Echo_impl.html new file mode 100644 index 0000000000000..7517eb090f496 --- /dev/null +++ b/tests/rustdoc/where.SWhere_Echo_impl.html @@ -0,0 +1,2 @@ +

impl<D> Delta<D>where + D: MyTrait,

\ No newline at end of file diff --git a/tests/rustdoc/where.SWhere_Simd_item-decl.html b/tests/rustdoc/where.SWhere_Simd_item-decl.html index ef4294c8f76d3..3e72ba2b74fe2 100644 --- a/tests/rustdoc/where.SWhere_Simd_item-decl.html +++ b/tests/rustdoc/where.SWhere_Simd_item-decl.html @@ -1,3 +1,3 @@
pub struct Simd<T>(_)
 where
-         T: MyTrait;
\ No newline at end of file + T: MyTrait; diff --git a/tests/rustdoc/where.alpha_trait_decl.html b/tests/rustdoc/where.alpha_trait_decl.html new file mode 100644 index 0000000000000..a7700055c9a74 --- /dev/null +++ b/tests/rustdoc/where.alpha_trait_decl.html @@ -0,0 +1,3 @@ +pub struct Alpha<A>(_) +where + A: MyTrait; \ No newline at end of file diff --git a/tests/rustdoc/where.bravo_trait_decl.html b/tests/rustdoc/where.bravo_trait_decl.html new file mode 100644 index 0000000000000..00524201a8aca --- /dev/null +++ b/tests/rustdoc/where.bravo_trait_decl.html @@ -0,0 +1,5 @@ +pub trait Bravo<B>where + B: MyTrait,{ + // Required method + fn get(&self, B: B); +} \ No newline at end of file diff --git a/tests/rustdoc/where.charlie_fn_decl.html b/tests/rustdoc/where.charlie_fn_decl.html new file mode 100644 index 0000000000000..8e3bc8b01ecbd --- /dev/null +++ b/tests/rustdoc/where.charlie_fn_decl.html @@ -0,0 +1,2 @@ +pub fn charlie<C>()where + C: MyTrait, \ No newline at end of file diff --git a/tests/rustdoc/where.golf_type_alias_decl.html b/tests/rustdoc/where.golf_type_alias_decl.html new file mode 100644 index 0000000000000..8da5402f90073 --- /dev/null +++ b/tests/rustdoc/where.golf_type_alias_decl.html @@ -0,0 +1,2 @@ +pub type Golf<T>where + T: Clone, = (T, T); \ No newline at end of file diff --git a/tests/rustdoc/where.rs b/tests/rustdoc/where.rs index 8b8a126e89dd5..2aa9c8b546193 100644 --- a/tests/rustdoc/where.rs +++ b/tests/rustdoc/where.rs @@ -5,16 +5,20 @@ use std::io::Lines; pub trait MyTrait { fn dummy(&self) { } } // @has foo/struct.Alpha.html '//pre' "pub struct Alpha(_) where A: MyTrait" +// @snapshot alpha_trait_decl - '//*[@class="rust item-decl"]/code' pub struct Alpha(A) where A: MyTrait; // @has foo/trait.Bravo.html '//pre' "pub trait Bravowhere B: MyTrait" +// @snapshot bravo_trait_decl - '//*[@class="rust item-decl"]/code' pub trait Bravo where B: MyTrait { fn get(&self, B: B); } // @has foo/fn.charlie.html '//pre' "pub fn charlie()where C: MyTrait" +// @snapshot charlie_fn_decl - '//*[@class="rust item-decl"]/code' pub fn charlie() where C: MyTrait {} pub struct Delta(D); // @has foo/struct.Delta.html '//*[@class="impl"]//h3[@class="code-header"]' \ // "impl Deltawhere D: MyTrait" +// @snapshot SWhere_Echo_impl - '//*[@id="impl-Delta%3CD%3E"]/h3[@class="code-header"]' impl Delta where D: MyTrait { pub fn delta() {} } @@ -65,4 +69,5 @@ impl MyTrait for Foxtrotwhere F: MyTrait {} // @has foo/type.Golf.html '//pre[@class="rust item-decl"]' \ // "type Golfwhere T: Clone, = (T, T)" +// @snapshot golf_type_alias_decl - '//*[@class="rust item-decl"]/code' pub type Golf where T: Clone = (T, T); From c8960622a2aa16987d1dc2372146a36faa31087a Mon Sep 17 00:00:00 2001 From: Takayuki Maeda Date: Fri, 23 Jun 2023 02:17:39 +0900 Subject: [PATCH 04/24] avoid `&format` in error message code --- compiler/rustc_borrowck/src/borrowck_errors.rs | 2 +- compiler/rustc_macros/src/diagnostics/error.rs | 10 ++++------ compiler/rustc_macros/src/diagnostics/subdiagnostic.rs | 2 +- compiler/rustc_macros/src/diagnostics/utils.rs | 2 +- 4 files changed, 7 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_borrowck/src/borrowck_errors.rs b/compiler/rustc_borrowck/src/borrowck_errors.rs index acca1a1477f25..a4e0e773a81ae 100644 --- a/compiler/rustc_borrowck/src/borrowck_errors.rs +++ b/compiler/rustc_borrowck/src/borrowck_errors.rs @@ -278,7 +278,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { move_from_span: Span, move_from_desc: &str, ) -> DiagnosticBuilder<'cx, ErrorGuaranteed> { - struct_span_err!(self, move_from_span, E0507, "cannot move out of {}", move_from_desc,) + struct_span_err!(self, move_from_span, E0507, "cannot move out of {}", move_from_desc) } /// Signal an error due to an attempt to move out of the interior diff --git a/compiler/rustc_macros/src/diagnostics/error.rs b/compiler/rustc_macros/src/diagnostics/error.rs index b37dc826d2886..84b18a6202814 100644 --- a/compiler/rustc_macros/src/diagnostics/error.rs +++ b/compiler/rustc_macros/src/diagnostics/error.rs @@ -54,7 +54,7 @@ fn path_to_string(path: &syn::Path) -> String { /// Returns an error diagnostic on span `span` with msg `msg`. #[must_use] -pub(crate) fn span_err(span: impl MultiSpan, msg: &str) -> Diagnostic { +pub(crate) fn span_err>(span: impl MultiSpan, msg: T) -> Diagnostic { Diagnostic::spanned(span, Level::Error, msg) } @@ -77,11 +77,9 @@ pub(crate) fn invalid_attr(attr: &Attribute) -> Diagnostic { let span = attr.span().unwrap(); let path = path_to_string(attr.path()); match attr.meta { - Meta::Path(_) => span_err(span, &format!("`#[{path}]` is not a valid attribute")), - Meta::NameValue(_) => { - span_err(span, &format!("`#[{path} = ...]` is not a valid attribute")) - } - Meta::List(_) => span_err(span, &format!("`#[{path}(...)]` is not a valid attribute")), + Meta::Path(_) => span_err(span, format!("`#[{path}]` is not a valid attribute")), + Meta::NameValue(_) => span_err(span, format!("`#[{path} = ...]` is not a valid attribute")), + Meta::List(_) => span_err(span, format!("`#[{path}(...)]` is not a valid attribute")), } } diff --git a/compiler/rustc_macros/src/diagnostics/subdiagnostic.rs b/compiler/rustc_macros/src/diagnostics/subdiagnostic.rs index e3d9eb96574d1..e8dc986914ed2 100644 --- a/compiler/rustc_macros/src/diagnostics/subdiagnostic.rs +++ b/compiler/rustc_macros/src/diagnostics/subdiagnostic.rs @@ -200,7 +200,7 @@ impl<'parent, 'a> SubdiagnosticDeriveVariantBuilder<'parent, 'a> { throw_span_err!( attr.span().unwrap(), - &format!( + format!( "diagnostic slug must be first argument of a `#[{name}(...)]` attribute" ) ); diff --git a/compiler/rustc_macros/src/diagnostics/utils.rs b/compiler/rustc_macros/src/diagnostics/utils.rs index 85dd9f6a3ce36..125632921816b 100644 --- a/compiler/rustc_macros/src/diagnostics/utils.rs +++ b/compiler/rustc_macros/src/diagnostics/utils.rs @@ -347,7 +347,7 @@ pub(crate) trait HasFieldMap { None => { span_err( span.unwrap(), - &format!("`{field}` doesn't refer to a field on this type"), + format!("`{field}` doesn't refer to a field on this type"), ) .emit(); quote! { From 9637d4401481a715e4451db8a6d3744b674eea7e Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Thu, 22 Jun 2023 11:53:49 -0700 Subject: [PATCH 05/24] style-guide: Fix typo "does done fit" should have been "does not fit". --- src/doc/style-guide/src/expressions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/style-guide/src/expressions.md b/src/doc/style-guide/src/expressions.md index 96f66c89c259f..8271b42da4c70 100644 --- a/src/doc/style-guide/src/expressions.md +++ b/src/doc/style-guide/src/expressions.md @@ -690,7 +690,7 @@ Where it is possible to use a block form on the right-hand side and avoid breaking the left-hand side, do that. E.g. ```rust - // Assuming the following line does done fit in the max width + // Assuming the following line does not fit in the max width a_very_long_pattern | another_pattern => ALongStructName { ... }, From 3747d7f593555cdf25d35aeaae8a66d5018eadbf Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Thu, 22 Jun 2023 12:30:14 -0700 Subject: [PATCH 06/24] style-guide: Move text about block vs visual indent to indentation section `principles.md` includes some high-level guiding principles for formatting, but also includes a few specific formatting provisions. While those provisions apply in many places, the same holds true for other high-level guidance, such as the indentation section. Move the text about using block indent rather than visual indent to the indentation section, so that `principles.md` can focus on guiding principles while the top level of the style guide gives concrete formatting recommendations. --- src/doc/style-guide/src/README.md | 18 ++++++++++++++++++ src/doc/style-guide/src/principles.md | 17 ----------------- 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/src/doc/style-guide/src/README.md b/src/doc/style-guide/src/README.md index adb73a7eef6e0..49a4bce2f5dcd 100644 --- a/src/doc/style-guide/src/README.md +++ b/src/doc/style-guide/src/README.md @@ -30,6 +30,24 @@ typically by using a formatting tool's default settings. * The maximum width for a line is 100 characters. * A tool should be configurable for all three of these variables. +#### Block indent + +Prefer block indent over visual indent: + +```rust +// Block indent +a_function_call( + foo, + bar, +); + +// Visual indent +a_function_call(foo, + bar); +``` + +This makes for smaller diffs (e.g., if `a_function_call` is renamed in the above +example) and less rightward drift. ### Blank lines diff --git a/src/doc/style-guide/src/principles.md b/src/doc/style-guide/src/principles.md index 2d203f264e623..c3104e6d9b60f 100644 --- a/src/doc/style-guide/src/principles.md +++ b/src/doc/style-guide/src/principles.md @@ -31,23 +31,6 @@ following principles (in rough priority order): ## Overarching guidelines -Prefer block indent over visual indent. E.g., - -```rust -// Block indent -a_function_call( - foo, - bar, -); - -// Visual indent -a_function_call(foo, - bar); -``` - -This makes for smaller diffs (e.g., if `a_function_call` is renamed in the above -example) and less rightward drift. - Lists should have a trailing comma when followed by a newline, see the block indent example above. This choice makes moving code (e.g., by copy and paste) easier and makes smaller diffs. From 92805672c3703c43481103bd1e81b12844a87b74 Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Thu, 22 Jun 2023 12:41:30 -0700 Subject: [PATCH 07/24] style-guide: Move and expand text about trailing commas `principles.md` includes some high-level guiding principles for formatting, but also includes a few specific formatting provisions. While those provisions apply in many places, the same holds true for other high-level guidance. Move the text about trailing commas to `README.md`, so that `principles.md` can focus on guiding principles while the top level of the style guide gives concrete formatting recommendations. --- src/doc/style-guide/src/README.md | 21 +++++++++++++++++++++ src/doc/style-guide/src/principles.md | 7 ------- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/doc/style-guide/src/README.md b/src/doc/style-guide/src/README.md index 49a4bce2f5dcd..3d47e33841a54 100644 --- a/src/doc/style-guide/src/README.md +++ b/src/doc/style-guide/src/README.md @@ -49,6 +49,27 @@ a_function_call(foo, This makes for smaller diffs (e.g., if `a_function_call` is renamed in the above example) and less rightward drift. +### Trailing commas + +Lists should have a trailing comma when followed by a newline: + +```rust +function_call( + argument, + another_argument, +); + +let array = [ + element, + another_element, + yet_another_element, +]; +``` + +This makes moving code (e.g., by copy and paste) easier, and makes diffs +smaller, as appending or removing items does not require modifying another line +to add or remove a comma. + ### Blank lines Separate items and statements by either zero or one blank lines (i.e., one or diff --git a/src/doc/style-guide/src/principles.md b/src/doc/style-guide/src/principles.md index c3104e6d9b60f..c86121e6a4697 100644 --- a/src/doc/style-guide/src/principles.md +++ b/src/doc/style-guide/src/principles.md @@ -27,10 +27,3 @@ following principles (in rough priority order): - ease of implementation (in Rustfmt, and in other tools/editors/code generators) - internal consistency - simplicity of formatting rules - - -## Overarching guidelines - -Lists should have a trailing comma when followed by a newline, see the block -indent example above. This choice makes moving code (e.g., by copy and paste) -easier and makes smaller diffs. From 2c0dd90936a5ce6a61cbe0f342b452871409b71c Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Thu, 22 Jun 2023 12:42:57 -0700 Subject: [PATCH 08/24] style-guide: s/right-ward/rightward/ We already use the word "rightward" elsewhere; avoid the unnecessarily hyphenated "right-ward". --- src/doc/style-guide/src/principles.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/style-guide/src/principles.md b/src/doc/style-guide/src/principles.md index c86121e6a4697..30fb26014f272 100644 --- a/src/doc/style-guide/src/principles.md +++ b/src/doc/style-guide/src/principles.md @@ -19,7 +19,7 @@ following principles (in rough priority order): * specifics - compatibility with version control practices - preserving diffs, merge-friendliness, etc. - - preventing right-ward drift + - preventing rightward drift - minimising vertical space * application From 4c5bb06a97515c1135e9339e6fa1fd78e7531ba2 Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Thu, 22 Jun 2023 12:45:56 -0700 Subject: [PATCH 09/24] style-guide: Consistently refer to rustfmt as `rustfmt` --- src/doc/style-guide/src/README.md | 4 ++-- src/doc/style-guide/src/items.md | 4 ++-- src/doc/style-guide/src/principles.md | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/doc/style-guide/src/README.md b/src/doc/style-guide/src/README.md index 3d47e33841a54..78e1d6a1fa184 100644 --- a/src/doc/style-guide/src/README.md +++ b/src/doc/style-guide/src/README.md @@ -16,8 +16,8 @@ Rust code has similar formatting, less mental effort is required to comprehend a new project, lowering the barrier to entry for new developers. Thus, there are productivity benefits to using a formatting tool (such as -rustfmt), and even larger benefits by using a community-consistent formatting, -typically by using a formatting tool's default settings. +`rustfmt`), and even larger benefits by using a community-consistent +formatting, typically by using a formatting tool's default settings. ## Formatting conventions diff --git a/src/doc/style-guide/src/items.md b/src/doc/style-guide/src/items.md index 2835975355fca..a9c559d0bb8c9 100644 --- a/src/doc/style-guide/src/items.md +++ b/src/doc/style-guide/src/items.md @@ -505,8 +505,8 @@ use b; Because of `macro_use`, attributes must also start a new group and prevent re-ordering. -Note that tools which only have access to syntax (such as Rustfmt) cannot tell -which imports are from an external crate or the std lib, etc. +Note that tools which only have access to syntax (such as `rustfmt`) cannot +tell which imports are from an external crate or the std lib, etc. #### Ordering list import diff --git a/src/doc/style-guide/src/principles.md b/src/doc/style-guide/src/principles.md index 30fb26014f272..bbf6d76d4216e 100644 --- a/src/doc/style-guide/src/principles.md +++ b/src/doc/style-guide/src/principles.md @@ -24,6 +24,6 @@ following principles (in rough priority order): * application - ease of manual application - - ease of implementation (in Rustfmt, and in other tools/editors/code generators) + - ease of implementation (in `rustfmt`, and in other tools/editors/code generators) - internal consistency - simplicity of formatting rules From d270af31972b2673ef0b05a5749a49f8a68a3d2b Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Thu, 22 Jun 2023 12:47:24 -0700 Subject: [PATCH 10/24] style-guide: Remove inaccurate statement about rustfmt rustfmt does include a mechanism to distinguish standard library imports, which it does syntactically by crate name. Avoid making a misleading statement that implies it cannot do this. --- src/doc/style-guide/src/items.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/doc/style-guide/src/items.md b/src/doc/style-guide/src/items.md index a9c559d0bb8c9..06ee4e28ccbc5 100644 --- a/src/doc/style-guide/src/items.md +++ b/src/doc/style-guide/src/items.md @@ -505,10 +505,6 @@ use b; Because of `macro_use`, attributes must also start a new group and prevent re-ordering. -Note that tools which only have access to syntax (such as `rustfmt`) cannot -tell which imports are from an external crate or the std lib, etc. - - #### Ordering list import Names in a list import must be sorted ascii-betically, but with `self` and From c5f8b2c7a92bc542c0c2666dc4672493cf945982 Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Thu, 22 Jun 2023 13:01:45 -0700 Subject: [PATCH 11/24] style-guide: Define (and capitalize) "ASCIIbetically" The style guide didn't give any definition for it. --- src/doc/style-guide/src/items.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/doc/style-guide/src/items.md b/src/doc/style-guide/src/items.md index 06ee4e28ccbc5..f1f5344f3e2cd 100644 --- a/src/doc/style-guide/src/items.md +++ b/src/doc/style-guide/src/items.md @@ -478,8 +478,8 @@ foo::{ A *group* of imports is a set of imports on the same or sequential lines. One or more blank lines or other items (e.g., a function) separate groups of imports. -Within a group of imports, imports must be sorted ascii-betically. Groups of -imports must not be merged or re-ordered. +Within a group of imports, imports must be sorted ASCIIbetically (uppercase +before lowercase). Groups of imports must not be merged or re-ordered. E.g., input: @@ -507,7 +507,7 @@ re-ordering. #### Ordering list import -Names in a list import must be sorted ascii-betically, but with `self` and +Names in a list import must be sorted ASCIIbetically, but with `self` and `super` first, and groups and glob imports last. This applies recursively. For example, `a::*` comes before `b::a` but `a::b` comes before `a::*`. E.g., `use foo::bar::{a, b::c, b::d, b::d::{x, y, z}, b::{self, r, s}};`. From 20f2828bbd37ce3d91797a2f2243c76190856301 Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Thu, 22 Jun 2023 13:12:43 -0700 Subject: [PATCH 12/24] style-guide: Update cargo.md for authors being optional and not recommended Change an example using the authors field to use a long feature list instead. Change the conventions for the authors field to say "if present". --- src/doc/style-guide/src/cargo.md | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/doc/style-guide/src/cargo.md b/src/doc/style-guide/src/cargo.md index 13b96ca8c5e9d..5e6a62a7fd284 100644 --- a/src/doc/style-guide/src/cargo.md +++ b/src/doc/style-guide/src/cargo.md @@ -25,16 +25,17 @@ not indent any key names; start all key names at the start of a line. Use multi-line strings (rather than newline escape sequences) for any string values that include multiple lines, such as the crate description. -For array values, such as a list of authors, put the entire list on the same +For array values, such as a list of features, put the entire list on the same line as the key, if it fits. Otherwise, use block indentation: put a newline after the opening square bracket, indent each item by one indentation level, put a comma after each item (including the last), and put the closing square bracket at the start of a line by itself after the last item. ```rust -authors = [ - "A Uthor ", - "Another Author ", +some_feature = [ + "another_feature", + "yet_another_feature", + "some_dependency?/some_feature", ] ``` @@ -54,11 +55,11 @@ version = "4.5.6" ## Metadata conventions -The authors list should consist of strings that each contain an author name -followed by an email address in angle brackets: `Full Name `. -It should not contain bare email addresses, or names without email addresses. -(The authors list may also include a mailing list address without an associated -name.) +The authors list, if present, should consist of strings that each contain an +author name followed by an email address in angle brackets: `Full Name +`. It should not contain bare email addresses, or names without +email addresses. (The authors list may also include a mailing list address +without an associated name.) The license field must contain a valid [SPDX expression](https://spdx.org/spdx-specification-21-web-version#h.jxpfx0ykyb60), From 6f8f83f66d88afe1e7d40011f8862844d8fa86c4 Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Thu, 22 Jun 2023 13:17:47 -0700 Subject: [PATCH 13/24] style-guide: Avoid normative recommendations for formatting tool configurability It's not within the scope of the style guide to tell formatting tools whether, or how, to allow configurability of non-default formatting. --- src/doc/style-guide/src/README.md | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/doc/style-guide/src/README.md b/src/doc/style-guide/src/README.md index 78e1d6a1fa184..2ad834f804bd0 100644 --- a/src/doc/style-guide/src/README.md +++ b/src/doc/style-guide/src/README.md @@ -28,7 +28,7 @@ formatting, typically by using a formatting tool's default settings. * Each level of indentation must be four spaces (that is, all indentation outside of string literals and comments must be a multiple of four). * The maximum width for a line is 100 characters. -* A tool should be configurable for all three of these variables. +* A tool may choose to make some of these configurable. #### Block indent @@ -87,11 +87,7 @@ fn bar() {} fn baz() {} ``` -Formatting tools should make the bounds on blank lines configurable: there -should be separate minimum and maximum numbers of newlines between both -statements and (top-level) items (i.e., four options). As described above, the -defaults for both statements and items should be minimum: 1, maximum: 2. - +Formatting tools may wish to make the bounds on blank lines configurable. ### [Module-level items](items.md) ### [Statements](statements.md) From fec28b26b5b6252cdd153135d61f54de4f2d10fb Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Thu, 22 Jun 2023 13:21:40 -0700 Subject: [PATCH 14/24] style-guide: Clarify advice on names matching keywords In particular, specify what this advice is an alternative to (creative misspellings such as `krate`). --- src/doc/style-guide/src/advice.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/doc/style-guide/src/advice.md b/src/doc/style-guide/src/advice.md index ab4b92b0a2478..9a617be509c38 100644 --- a/src/doc/style-guide/src/advice.md +++ b/src/doc/style-guide/src/advice.md @@ -25,9 +25,9 @@ if y { * Local variables shall be `snake_case`, * Macro names shall be `snake_case`, * Constants (`const`s and immutable `static`s) shall be `SCREAMING_SNAKE_CASE`. - * When a name is forbidden because it is a reserved word (e.g., `crate`), use a - trailing underscore to make the name legal (e.g., `crate_`), or use raw - identifiers if possible. + * When a name is forbidden because it is a reserved word (such as `crate`), + either use a raw identifier (`r#crate`) or use a trailing underscore + (`crate_`). Don't misspell the word (`krate`). ### Modules From 2828c5605eb57ead02036c3a0307932ebf8dae9d Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Thu, 22 Jun 2023 23:01:48 +0200 Subject: [PATCH 15/24] typo --- tests/ui/use/use-keyword.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/ui/use/use-keyword.rs b/tests/ui/use/use-keyword.rs index c30c2e06c4557..840cddcb907cc 100644 --- a/tests/ui/use/use-keyword.rs +++ b/tests/ui/use/use-keyword.rs @@ -1,4 +1,4 @@ -// Check that imports with nakes super and self don't fail during parsing +// Check that imports with naked super and self don't fail during parsing // FIXME: this shouldn't fail during name resolution either mod a { From c930b21bcdf9a47fd299e150f8056fe5f7bd7a08 Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Thu, 22 Jun 2023 13:28:47 -0700 Subject: [PATCH 16/24] style-guide: Reword an awkwardly phrased recommendation (and fix a typo) --- src/doc/style-guide/src/items.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/doc/style-guide/src/items.md b/src/doc/style-guide/src/items.md index f1f5344f3e2cd..79635e758f31b 100644 --- a/src/doc/style-guide/src/items.md +++ b/src/doc/style-guide/src/items.md @@ -15,8 +15,8 @@ Tools should make the above ordering optional. ### Function definitions -In Rust, one finds functions by searching for `fn [function-name]`; It's -important that you style your code so that it's very searchable in this way. +In Rust, people often find functions by searching for `fn [function-name]`, so +the formatting of function definitions shold enable this. The proper ordering and spacing is: From 3e2449c2b14eb676a27d2b62a162a800c6e89212 Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Thu, 22 Jun 2023 13:30:06 -0700 Subject: [PATCH 17/24] style-guide: Rephrase a confusingly ordered, ambiguous sentence (and fix a typo) This sentence had a parenthetical without a closing parenthesis, and had the phrase "which doesn't require special formatting" ambiguously at the end of a list when it only applied to the last item of the list. --- src/doc/style-guide/src/items.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/doc/style-guide/src/items.md b/src/doc/style-guide/src/items.md index 79635e758f31b..41ac1eeca96a5 100644 --- a/src/doc/style-guide/src/items.md +++ b/src/doc/style-guide/src/items.md @@ -63,8 +63,9 @@ let y = (11, 22, 33); In the declaration, put each variant on its own line, block indented. -Format each variant accordingly as either a struct, tuple struct, or identifier, -which doesn't require special formatting (but without the `struct` keyword. +Format each variant accordingly as either a struct (but without the `struct` +keyword), a tuple struct, or an identifier (which doesn't require special +formatting): ```rust enum FooBar { From a9d1db31457f8ae619bb73234632b20ccc8b930f Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Thu, 22 Jun 2023 13:57:49 -0700 Subject: [PATCH 18/24] style-guide: Avoid hyphenating "semicolon" --- src/doc/style-guide/src/items.md | 6 +++--- src/doc/style-guide/src/statements.md | 10 +++++----- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/doc/style-guide/src/items.md b/src/doc/style-guide/src/items.md index 41ac1eeca96a5..8a0954f53430e 100644 --- a/src/doc/style-guide/src/items.md +++ b/src/doc/style-guide/src/items.md @@ -140,7 +140,7 @@ union Foo { Put the whole struct on one line if possible. Types in the parentheses should be separated by a comma and space with no trailing comma. No spaces around the -parentheses or semi-colon: +parentheses or semicolon: ```rust pub struct Foo(String, u8); @@ -231,7 +231,7 @@ impl Bar `extern crate foo;` -Use spaces around keywords, no spaces around the semi-colon. +Use spaces around keywords, no spaces around the semicolon. ### Modules @@ -246,7 +246,7 @@ mod foo; ``` Use spaces around keywords and before the opening brace, no spaces around the -semi-colon. +semicolon. ### macro\_rules! diff --git a/src/doc/style-guide/src/statements.md b/src/doc/style-guide/src/statements.md index 671e6d31a5775..abb6b492b9121 100644 --- a/src/doc/style-guide/src/statements.md +++ b/src/doc/style-guide/src/statements.md @@ -1,7 +1,7 @@ ### Let statements There should be spaces after the `:` and on both sides of the `=` (if they are -present). No space before the semi-colon. +present). No space before the semicolon. ```rust // A comment. @@ -194,7 +194,7 @@ used to determine whether a let-else statement is *short*. ### Macros in statement position A macro use in statement position should use parentheses or square brackets as -delimiters and should be terminated with a semi-colon. There should be no spaces +delimiters and should be terminated with a semicolon. There should be no spaces between the name, `!`, the delimiters, or the `;`. ```rust @@ -205,13 +205,13 @@ a_macro!(...); ### Expressions in statement position -There should be no space between the expression and the semi-colon. +There should be no space between the expression and the semicolon. ``` ; ``` -All expressions in statement position should be terminated with a semi-colon, +All expressions in statement position should be terminated with a semicolon, unless they end with a block or are used as the value for a block. E.g., @@ -229,7 +229,7 @@ loop { } ``` -Use a semi-colon where an expression has void type, even if it could be +Use a semicolon where an expression has void type, even if it could be propagated. E.g., ```rust From 5d637219e43ed61f05f0c4e9c48f9b692a8c1147 Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Thu, 22 Jun 2023 14:02:22 -0700 Subject: [PATCH 19/24] style-guide: Make link text in SUMMARY.md match the headings in the linked pages --- src/doc/style-guide/src/SUMMARY.md | 8 ++++---- src/doc/style-guide/src/cargo.md | 2 +- src/doc/style-guide/src/statements.md | 2 ++ 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/doc/style-guide/src/SUMMARY.md b/src/doc/style-guide/src/SUMMARY.md index 004692fa6a22b..59fe9fdc6694a 100644 --- a/src/doc/style-guide/src/SUMMARY.md +++ b/src/doc/style-guide/src/SUMMARY.md @@ -2,10 +2,10 @@ [Introduction](README.md) -- [Module-level items](items.md) +- [Items](items.md) - [Statements](statements.md) - [Expressions](expressions.md) -- [Types](types.md) -- [Non-formatting conventions](advice.md) +- [Types and Bounds](types.md) +- [Other style advice](advice.md) - [`Cargo.toml` conventions](cargo.md) -- [Principles used for deciding these guidelines](principles.md) +- [Guiding principles and rationale](principles.md) diff --git a/src/doc/style-guide/src/cargo.md b/src/doc/style-guide/src/cargo.md index 5e6a62a7fd284..d3b67ae45825d 100644 --- a/src/doc/style-guide/src/cargo.md +++ b/src/doc/style-guide/src/cargo.md @@ -1,4 +1,4 @@ -# Cargo.toml conventions +# `Cargo.toml` conventions ## Formatting conventions diff --git a/src/doc/style-guide/src/statements.md b/src/doc/style-guide/src/statements.md index abb6b492b9121..62a5a032f072e 100644 --- a/src/doc/style-guide/src/statements.md +++ b/src/doc/style-guide/src/statements.md @@ -1,3 +1,5 @@ +## Statements + ### Let statements There should be spaces after the `:` and on both sides of the `=` (if they are From f972e09f76e5d5557a56026b4ffa78eb76df6564 Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Thu, 22 Jun 2023 14:06:15 -0700 Subject: [PATCH 20/24] style-guide: Define what an item is --- src/doc/style-guide/src/items.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/doc/style-guide/src/items.md b/src/doc/style-guide/src/items.md index 8a0954f53430e..1e0e60248bfbd 100644 --- a/src/doc/style-guide/src/items.md +++ b/src/doc/style-guide/src/items.md @@ -1,5 +1,10 @@ ## Items +Items consist of the set of things permitted at the top level of a module. +However, Rust also allows some items to appear within some other types of +items, such as within a function. The same formatting conventions apply whether +an item appears at module level or within another item. + `extern crate` statements must be first in a file. They must be ordered alphabetically. From fcc23a3bfd827b5c587e4899a6fe6b92d72c048e Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Thu, 22 Jun 2023 12:50:04 -0700 Subject: [PATCH 21/24] style-guide: Avoid referring to the style team in the past tense We live! --- src/doc/style-guide/src/principles.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/doc/style-guide/src/principles.md b/src/doc/style-guide/src/principles.md index bbf6d76d4216e..d548693e39ed0 100644 --- a/src/doc/style-guide/src/principles.md +++ b/src/doc/style-guide/src/principles.md @@ -1,7 +1,7 @@ # Guiding principles and rationale -When deciding on style guidelines, the style team tried to be guided by the -following principles (in rough priority order): +When deciding on style guidelines, the style team follows these guiding +principles (in rough priority order): * readability - scan-ability From 2748efaba3ed81de50a8e23ce72c9bb214e11fe5 Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Thu, 22 Jun 2023 14:39:15 -0700 Subject: [PATCH 22/24] style-guide: Add language disclaiming any effects on non-default Rust styles Make it clear that the style guide saying "must" doesn't forbid developers from doing differently (as though any power on this Earth could do that) and doesn't forbid tools from allowing any particular configuration options. --- src/doc/style-guide/src/README.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/doc/style-guide/src/README.md b/src/doc/style-guide/src/README.md index adb73a7eef6e0..d57b4be0b85d2 100644 --- a/src/doc/style-guide/src/README.md +++ b/src/doc/style-guide/src/README.md @@ -19,6 +19,18 @@ Thus, there are productivity benefits to using a formatting tool (such as rustfmt), and even larger benefits by using a community-consistent formatting, typically by using a formatting tool's default settings. +## The default Rust style + +The Rust Style Guide defines the default Rust style, and *recommends* that +developers and tools follow the default Rust style. Tools such as `rustfmt` use +the style guide as a reference for the default style. Everything in this style +guide, whether or not it uses language such as "must" or the imperative mood +such as "insert a space ..." or "break the line after ...", refers to the +default style. + +This should not be interpreted as forbidding developers from following a +non-default style, or forbidding tools from adding any particular configuration +options. ## Formatting conventions From afe36507e84e8b7805717bc1c5054dcf4346df92 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 19 May 2023 00:10:06 +0000 Subject: [PATCH 23/24] Don't structurally resolve during method ambiguity in probe --- compiler/rustc_hir_typeck/src/method/probe.rs | 19 ++++++--- .../deref-ambiguity-becomes-nonambiguous.rs | 40 +++++++++++++++++++ ...eref-ambiguity-becomes-nonambiguous.stderr | 17 ++++++++ 3 files changed, 71 insertions(+), 5 deletions(-) create mode 100644 tests/ui/autoref-autoderef/deref-ambiguity-becomes-nonambiguous.rs create mode 100644 tests/ui/autoref-autoderef/deref-ambiguity-becomes-nonambiguous.stderr diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index e759fd6bc948a..762176ecfc795 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -12,6 +12,7 @@ use rustc_hir::def::DefKind; use rustc_hir_analysis::autoderef::{self, Autoderef}; use rustc_infer::infer::canonical::OriginalQueryValues; use rustc_infer::infer::canonical::{Canonical, QueryResponse}; +use rustc_infer::infer::error_reporting::TypeAnnotationNeeded::E0282; use rustc_infer::infer::DefineOpaqueTypes; use rustc_infer::infer::{self, InferOk, TyCtxtInferExt}; use rustc_middle::middle::stability; @@ -448,15 +449,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ); } } else { - // Encountered a real ambiguity, so abort the lookup. If `ty` is not - // an `Err`, report the right "type annotations needed" error pointing - // to it. + // Ended up encountering a type variable when doing autoderef, + // but it may not be a type variable after processing obligations + // in our local `FnCtxt`, so don't call `structurally_resolved_type`. let ty = &bad_ty.ty; let ty = self .probe_instantiate_query_response(span, &orig_values, ty) .unwrap_or_else(|_| span_bug!(span, "instantiating {:?} failed?", ty)); - let ty = self.structurally_resolved_type(span, ty.value); - assert!(matches!(ty.kind(), ty::Error(_))); + let ty = self.resolve_vars_if_possible(ty.value); + let guar = match *ty.kind() { + ty::Infer(ty::TyVar(_)) => self + .err_ctxt() + .emit_inference_failure_err(self.body_id, span, ty.into(), E0282, true) + .emit(), + ty::Error(guar) => guar, + _ => bug!("unexpected bad final type in method autoderef"), + }; + self.demand_eqtype(span, ty, self.tcx.ty_error(guar)); return Err(MethodError::NoMatch(NoMatchData { static_candidates: Vec::new(), unsatisfied_predicates: Vec::new(), diff --git a/tests/ui/autoref-autoderef/deref-ambiguity-becomes-nonambiguous.rs b/tests/ui/autoref-autoderef/deref-ambiguity-becomes-nonambiguous.rs new file mode 100644 index 0000000000000..d8034d57e8d56 --- /dev/null +++ b/tests/ui/autoref-autoderef/deref-ambiguity-becomes-nonambiguous.rs @@ -0,0 +1,40 @@ +use std::ops::Deref; +use std::rc::Rc; + +struct Value(T); + +pub trait Wrap { + fn wrap() -> Self; +} + +impl Wrap R> for Value R> { + fn wrap() -> Self { + todo!() + } +} + +impl Wrap for Value R>> { + fn wrap() -> Self { + todo!() + } +} + +impl Deref for Value> { + type Target = F; + + fn deref(&self) -> &Self::Target { + &*self.0 + } +} + +fn main() { + let var_fn = Value::wrap(); + //~^ ERROR type annotations needed for `Value>` + + // The combination of `Value: Wrap` obligation plus the autoderef steps + // (caused by the `Deref` impl above) actually means that the self type + // of the method fn below is constrained to be `Value ?2>>`. + // However, that's only known to us on the error path -- we still need + // to emit an ambiguity error, though. + let _ = var_fn.clone(); +} diff --git a/tests/ui/autoref-autoderef/deref-ambiguity-becomes-nonambiguous.stderr b/tests/ui/autoref-autoderef/deref-ambiguity-becomes-nonambiguous.stderr new file mode 100644 index 0000000000000..06a7e90858ce7 --- /dev/null +++ b/tests/ui/autoref-autoderef/deref-ambiguity-becomes-nonambiguous.stderr @@ -0,0 +1,17 @@ +error[E0282]: type annotations needed for `Value>` + --> $DIR/deref-ambiguity-becomes-nonambiguous.rs:31:9 + | +LL | let var_fn = Value::wrap(); + | ^^^^^^ +... +LL | let _ = var_fn.clone(); + | ----- type must be known at this point + | +help: consider giving `var_fn` an explicit type, where the placeholders `_` are specified + | +LL | let var_fn: Value> = Value::wrap(); + | ++++++++++++++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0282`. From 48167bd4bddec03d1969e2cc2c1155cb5667d6ad Mon Sep 17 00:00:00 2001 From: Alexander Zhang Date: Thu, 22 Jun 2023 16:37:52 -0700 Subject: [PATCH 24/24] Avoid guessing unknown trait impl in suggestions When a trait is used without specifying the implementation (e.g. calling a non-member associated function without fully-qualified syntax) and there are multiple implementations available, use a placeholder comment for the implementation type in the suggestion instead of picking a random implementation. Example: ``` fn main() { let _ = Default::default(); } ``` Previous output: ``` error[E0790]: cannot call associated function on trait without specifying the corresponding `impl` type --> test.rs:2:13 | 2 | let _ = Default::default(); | ^^^^^^^^^^^^^^^^ cannot call associated function of trait | help: use a fully-qualified path to a specific available implementation (273 found) | 2 | let _ = ::default(); | +++++++++++++ + ``` New output: ``` error[E0790]: cannot call associated function on trait without specifying the corresponding `impl` type --> test.rs:2:13 | 2 | let _ = Default::default(); | ^^^^^^^^^^^^^^^^ cannot call associated function of trait | help: use a fully-qualified path to a specific available implementation (273 found) | 2 | let _ = ::default(); | +++++++++++++++++++ + ``` --- .../src/traits/error_reporting/mod.rs | 16 ++++++++++------ tests/ui/error-codes/E0283.stderr | 4 ++-- tests/ui/error-codes/E0790.stderr | 4 ++-- 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index 75a92af714bd5..67745f04641ab 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -2382,17 +2382,21 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { && let Some(impl_def_id) = trait_impls.non_blanket_impls().values().flatten().next() { let non_blanket_impl_count = trait_impls.non_blanket_impls().values().flatten().count(); - let message = if non_blanket_impl_count == 1 { - "use the fully-qualified path to the only available implementation".to_string() - } else { + // If there is only one implementation of the trait, suggest using it. + // Otherwise, use a placeholder comment for the implementation. + let (message, impl_suggestion) = if non_blanket_impl_count == 1 {( + "use the fully-qualified path to the only available implementation".to_string(), + format!("<{} as ", self.tcx.type_of(impl_def_id).subst_identity()) + )} else {( format!( "use a fully-qualified path to a specific available implementation ({} found)", non_blanket_impl_count - ) - }; + ), + "::create(); - | ++++++++ + +LL | let cont: u32 = ::create(); + | +++++++++++++++++++ + error[E0283]: type annotations needed --> $DIR/E0283.rs:35:24 diff --git a/tests/ui/error-codes/E0790.stderr b/tests/ui/error-codes/E0790.stderr index fc025a3fca2bf..7248766285d71 100644 --- a/tests/ui/error-codes/E0790.stderr +++ b/tests/ui/error-codes/E0790.stderr @@ -65,8 +65,8 @@ LL | MyTrait2::my_fn(); | help: use a fully-qualified path to a specific available implementation (2 found) | -LL | ::my_fn(); - | +++++++++ + +LL | ::my_fn(); + | +++++++++++++++++++ + error: aborting due to 5 previous errors