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_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/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! { 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 - ) - }; + ), + "()` 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. diff --git a/src/doc/style-guide/src/README.md b/src/doc/style-guide/src/README.md index adb73a7eef6e0..75013bb3df980 100644 --- a/src/doc/style-guide/src/README.md +++ b/src/doc/style-guide/src/README.md @@ -16,9 +16,21 @@ 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. +## 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 @@ -28,8 +40,47 @@ 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 + +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. + +### 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 @@ -48,11 +99,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) 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/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 diff --git a/src/doc/style-guide/src/cargo.md b/src/doc/style-guide/src/cargo.md index 13b96ca8c5e9d..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 @@ -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), 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 { ... }, diff --git a/src/doc/style-guide/src/items.md b/src/doc/style-guide/src/items.md index 2835975355fca..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. @@ -15,8 +20,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: @@ -63,8 +68,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 { @@ -139,7 +145,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); @@ -230,7 +236,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 @@ -245,7 +251,7 @@ mod foo; ``` Use spaces around keywords and before the opening brace, no spaces around the -semi-colon. +semicolon. ### macro\_rules! @@ -478,8 +484,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: @@ -505,13 +511,9 @@ 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 +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}};`. diff --git a/src/doc/style-guide/src/principles.md b/src/doc/style-guide/src/principles.md index 2d203f264e623..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 @@ -19,35 +19,11 @@ 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 - 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 - - -## 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. diff --git a/src/doc/style-guide/src/statements.md b/src/doc/style-guide/src/statements.md index 671e6d31a5775..62a5a032f072e 100644 --- a/src/doc/style-guide/src/statements.md +++ b/src/doc/style-guide/src/statements.md @@ -1,7 +1,9 @@ +## Statements + ### 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 +196,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 +207,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 +231,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 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 f15c9bacec0ee..f923f90545126 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -860,8 +860,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, 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); 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`. diff --git a/tests/ui/error-codes/E0283.stderr b/tests/ui/error-codes/E0283.stderr index 90316c6e981d8..89e634a7064a6 100644 --- a/tests/ui/error-codes/E0283.stderr +++ b/tests/ui/error-codes/E0283.stderr @@ -9,8 +9,8 @@ LL | let cont: u32 = Generator::create(); | help: use a fully-qualified path to a specific available implementation (2 found) | -LL | let cont: u32 = ::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 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 {