diff --git a/Cargo.lock b/Cargo.lock index 683331d472468..dc12737851e41 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2370,9 +2370,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-sys" -version = "0.9.84" +version = "0.9.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a20eace9dc2d82904039cb76dcf50fb1a0bba071cfd1629720b5d6f1ddba0fa" +checksum = "8e17f59264b2809d77ae94f0e1ebabc434773f370d6ca667bd223ea10e06cc7e" dependencies = [ "cc", "libc", diff --git a/compiler/rustc_arena/src/lib.rs b/compiler/rustc_arena/src/lib.rs index 236bdb99709e8..6e15f06a76de0 100644 --- a/compiler/rustc_arena/src/lib.rs +++ b/compiler/rustc_arena/src/lib.rs @@ -20,6 +20,7 @@ #![feature(rustc_attrs)] #![cfg_attr(test, feature(test))] #![feature(strict_provenance)] +#![deny(unsafe_op_in_unsafe_fn)] #![deny(rustc::untranslatable_diagnostic)] #![deny(rustc::diagnostic_outside_of_impl)] #![allow(clippy::mut_from_ref)] // Arena allocators are one of the places where this pattern is fine. @@ -74,19 +75,27 @@ impl ArenaChunk { #[inline] unsafe fn new(capacity: usize) -> ArenaChunk { ArenaChunk { - storage: NonNull::new_unchecked(Box::into_raw(Box::new_uninit_slice(capacity))), + storage: NonNull::from(Box::leak(Box::new_uninit_slice(capacity))), entries: 0, } } /// Destroys this arena chunk. + /// + /// # Safety + /// + /// The caller must ensure that `len` elements of this chunk have been initialized. #[inline] unsafe fn destroy(&mut self, len: usize) { // The branch on needs_drop() is an -O1 performance optimization. - // Without the branch, dropping TypedArena takes linear time. + // Without the branch, dropping TypedArena takes linear time. if mem::needs_drop::() { - let slice = self.storage.as_mut(); - ptr::drop_in_place(MaybeUninit::slice_assume_init_mut(&mut slice[..len])); + // SAFETY: The caller must ensure that `len` elements of this chunk have + // been initialized. + unsafe { + let slice = self.storage.as_mut(); + ptr::drop_in_place(MaybeUninit::slice_assume_init_mut(&mut slice[..len])); + } } } @@ -255,7 +264,9 @@ impl TypedArena { self.ensure_capacity(len); let start_ptr = self.ptr.get(); - self.ptr.set(start_ptr.add(len)); + // SAFETY: `self.ensure_capacity` makes sure that there is enough space + // for `len` elements. + unsafe { self.ptr.set(start_ptr.add(len)) }; start_ptr } @@ -483,6 +494,10 @@ impl DroplessArena { } } + /// # Safety + /// + /// The caller must ensure that `mem` is valid for writes up to + /// `size_of::() * len`. #[inline] unsafe fn write_from_iter>( &self, @@ -494,13 +509,18 @@ impl DroplessArena { // Use a manual loop since LLVM manages to optimize it better for // slice iterators loop { - let value = iter.next(); - if i >= len || value.is_none() { - // We only return as many items as the iterator gave us, even - // though it was supposed to give us `len` - return slice::from_raw_parts_mut(mem, i); + // SAFETY: The caller must ensure that `mem` is valid for writes up to + // `size_of::() * len`. + unsafe { + match iter.next() { + Some(value) if i < len => mem.add(i).write(value), + Some(_) | None => { + // We only return as many items as the iterator gave us, even + // though it was supposed to give us `len` + return slice::from_raw_parts_mut(mem, i); + } + } } - ptr::write(mem.add(i), value.unwrap()); i += 1; } } diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs index b8222820cf7a4..d5f4b3a32cd18 100644 --- a/compiler/rustc_hir_typeck/src/demand.rs +++ b/compiler/rustc_hir_typeck/src/demand.rs @@ -86,9 +86,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.emit_type_mismatch_suggestions(err, expr, expr_ty, expected, expected_ty_expr, error); self.note_type_is_not_clone(err, expected, expr_ty, expr); self.note_internal_mutation_in_method(err, expr, Some(expected), expr_ty); - self.check_for_range_as_method_call(err, expr, expr_ty, expected); - self.check_for_binding_assigned_block_without_tail_expression(err, expr, expr_ty, expected); - self.check_wrong_return_type_due_to_generic_arg(err, expr, expr_ty); + self.suggest_method_call_on_range_literal(err, expr, expr_ty, expected); + self.suggest_return_binding_for_missing_tail_expr(err, expr, expr_ty, expected); + self.note_wrong_return_ty_due_to_generic_arg(err, expr, expr_ty); } /// Requires that the two types unify, and prints an error message if @@ -1087,7 +1087,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// ```ignore (illustrative) /// opt.map(|param| { takes_ref(param) }); /// ``` - fn can_use_as_ref(&self, expr: &hir::Expr<'_>) -> Option<(Span, &'static str, String)> { + fn can_use_as_ref(&self, expr: &hir::Expr<'_>) -> Option<(Vec<(Span, String)>, &'static str)> { let hir::ExprKind::Path(hir::QPath::Resolved(_, ref path)) = expr.kind else { return None; }; @@ -1133,12 +1133,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } _ => false, }; - match (is_as_ref_able, self.sess().source_map().span_to_snippet(method_path.ident.span)) { - (true, Ok(src)) => { - let suggestion = format!("as_ref().{}", src); - Some((method_path.ident.span, "consider using `as_ref` instead", suggestion)) - } - _ => None, + if is_as_ref_able { + Some(( + vec![(method_path.ident.span.shrink_to_lo(), "as_ref().".to_string())], + "consider using `as_ref` instead", + )) + } else { + None } } @@ -1217,14 +1218,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// In addition of this check, it also checks between references mutability state. If the /// expected is mutable but the provided isn't, maybe we could just say "Hey, try with /// `&mut`!". - pub fn check_ref( + pub fn suggest_deref_or_ref( &self, expr: &hir::Expr<'tcx>, checked_ty: Ty<'tcx>, expected: Ty<'tcx>, ) -> Option<( - Span, - String, + Vec<(Span, String)>, String, Applicability, bool, /* verbose */ @@ -1254,30 +1254,28 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { && let Ok(src) = sm.span_to_snippet(sp) && replace_prefix(&src, "b\"", "\"").is_some() { - let pos = sp.lo() + BytePos(1); - return Some(( - sp.with_hi(pos), - "consider removing the leading `b`".to_string(), - String::new(), - Applicability::MachineApplicable, - true, - false, - )); - } - } + let pos = sp.lo() + BytePos(1); + return Some(( + vec![(sp.with_hi(pos), String::new())], + "consider removing the leading `b`".to_string(), + Applicability::MachineApplicable, + true, + false, + )); + } + } (&ty::Array(arr, _) | &ty::Slice(arr), &ty::Str) if arr == self.tcx.types.u8 => { if let hir::ExprKind::Lit(_) = expr.kind && let Ok(src) = sm.span_to_snippet(sp) && replace_prefix(&src, "\"", "b\"").is_some() { - return Some(( - sp.shrink_to_lo(), - "consider adding a leading `b`".to_string(), - "b".to_string(), - Applicability::MachineApplicable, - true, - false, - )); + return Some(( + vec![(sp.shrink_to_lo(), "b".to_string())], + "consider adding a leading `b`".to_string(), + Applicability::MachineApplicable, + true, + false, + )); } } _ => {} @@ -1320,66 +1318,73 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } if let hir::ExprKind::Unary(hir::UnOp::Deref, ref inner) = expr.kind - && let Some(1) = self.deref_steps(expected, checked_ty) { + && let Some(1) = self.deref_steps(expected, checked_ty) + { // We have `*&T`, check if what was expected was `&T`. // If so, we may want to suggest removing a `*`. sugg_sp = sugg_sp.with_hi(inner.span.lo()); return Some(( - sugg_sp, + vec![(sugg_sp, String::new())], "consider removing deref here".to_string(), - "".to_string(), Applicability::MachineApplicable, true, false, )); } - if let Ok(src) = sm.span_to_snippet(sugg_sp) { - let needs_parens = match expr.kind { - // parenthesize if needed (Issue #46756) - hir::ExprKind::Cast(_, _) | hir::ExprKind::Binary(_, _, _) => true, - // parenthesize borrows of range literals (Issue #54505) - _ if is_range_literal(expr) => true, - _ => false, - }; - - if let Some(sugg) = self.can_use_as_ref(expr) { - return Some(( - sugg.0, - sugg.1.to_string(), - sugg.2, - Applicability::MachineApplicable, - false, - false, - )); - } - - let prefix = match self.maybe_get_struct_pattern_shorthand_field(expr) { - Some(ident) => format!("{ident}: "), - None => String::new(), - }; - - if let Some(hir::Node::Expr(hir::Expr { - kind: hir::ExprKind::Assign(..), - .. - })) = self.tcx.hir().find_parent(expr.hir_id) - { - if mutability.is_mut() { - // Suppressing this diagnostic, we'll properly print it in `check_expr_assign` - return None; - } - } + let needs_parens = match expr.kind { + // parenthesize if needed (Issue #46756) + hir::ExprKind::Cast(_, _) | hir::ExprKind::Binary(_, _, _) => true, + // parenthesize borrows of range literals (Issue #54505) + _ if is_range_literal(expr) => true, + _ => false, + }; - let sugg_expr = if needs_parens { format!("({src})") } else { src }; + if let Some((sugg, msg)) = self.can_use_as_ref(expr) { return Some(( - sp, - format!("consider {}borrowing here", mutability.mutably_str()), - format!("{prefix}{}{sugg_expr}", mutability.ref_prefix_str()), + sugg, + msg.to_string(), Applicability::MachineApplicable, - false, + true, false, )); } + + let prefix = match self.maybe_get_struct_pattern_shorthand_field(expr) { + Some(ident) => format!("{ident}: "), + None => String::new(), + }; + + if let Some(hir::Node::Expr(hir::Expr { + kind: hir::ExprKind::Assign(..), + .. + })) = self.tcx.hir().find_parent(expr.hir_id) + { + if mutability.is_mut() { + // Suppressing this diagnostic, we'll properly print it in `check_expr_assign` + return None; + } + } + + let sugg = mutability.ref_prefix_str(); + let (sugg, verbose) = if needs_parens { + ( + vec![ + (sp.shrink_to_lo(), format!("{prefix}{sugg}(")), + (sp.shrink_to_hi(), ")".to_string()), + ], + false, + ) + } else { + (vec![(sp.shrink_to_lo(), format!("{prefix}{sugg}"))], true) + }; + return Some(( + sugg, + format!("consider {}borrowing here", mutability.mutably_str()), + Applicability::MachineApplicable, + verbose, + false, + )); } } ( @@ -1401,23 +1406,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { && sm.is_span_accessible(call_span) { return Some(( - sp.with_hi(call_span.lo()), + vec![(sp.with_hi(call_span.lo()), String::new())], "consider removing the borrow".to_string(), - String::new(), Applicability::MachineApplicable, true, - true + true, )); } return None; } - if sp.contains(expr.span) - && sm.is_span_accessible(expr.span) - { + if sp.contains(expr.span) && sm.is_span_accessible(expr.span) { return Some(( - sp.with_hi(expr.span.lo()), + vec![(sp.with_hi(expr.span.lo()), String::new())], "consider removing the borrow".to_string(), - String::new(), Applicability::MachineApplicable, true, true, @@ -1441,23 +1442,30 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let suggestion = replace_prefix(&src, old_prefix, &new_prefix).map(|_| { // skip `&` or `&mut ` if both mutabilities are mutable - let lo = sp.lo() + BytePos(min(old_prefix.len(), mutbl_b.ref_prefix_str().len()) as _); + let lo = sp.lo() + + BytePos(min(old_prefix.len(), mutbl_b.ref_prefix_str().len()) as _); // skip `&` or `&mut ` let hi = sp.lo() + BytePos(old_prefix.len() as _); let sp = sp.with_lo(lo).with_hi(hi); ( sp, - format!("{}{derefs}", if mutbl_a != mutbl_b { mutbl_b.prefix_str() } else { "" }), - if mutbl_b <= mutbl_a { Applicability::MachineApplicable } else { Applicability::MaybeIncorrect } + format!( + "{}{derefs}", + if mutbl_a != mutbl_b { mutbl_b.prefix_str() } else { "" } + ), + if mutbl_b <= mutbl_a { + Applicability::MachineApplicable + } else { + Applicability::MaybeIncorrect + }, ) }); if let Some((span, src, applicability)) = suggestion { return Some(( - span, + vec![(span, src)], "consider dereferencing".to_string(), - src, applicability, true, false, @@ -1486,9 +1494,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // If we've reached our target type with just removing `&`, then just print now. if steps == 0 && !remove.trim().is_empty() { return Some(( - prefix_span, + vec![(prefix_span, String::new())], format!("consider removing the `{}`", remove.trim()), - String::new(), // Do not remove `&&` to get to bool, because it might be something like // { a } && b, which we have a separate fixup suggestion that is more // likely correct... @@ -1554,9 +1561,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } return Some(( - span, + vec![(span, suggestion)], message, - suggestion, Applicability::MachineApplicable, true, false, @@ -1569,7 +1575,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { None } - pub fn check_for_cast( + pub fn suggest_cast( &self, err: &mut Diagnostic, expr: &hir::Expr<'_>, @@ -1939,7 +1945,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } /// Identify when the user has written `foo..bar()` instead of `foo.bar()`. - pub fn check_for_range_as_method_call( + pub fn suggest_method_call_on_range_literal( &self, err: &mut Diagnostic, expr: &hir::Expr<'tcx>, @@ -2008,7 +2014,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// Identify when the type error is because `()` is found in a binding that was assigned a /// block without a tail expression. - fn check_for_binding_assigned_block_without_tail_expression( + fn suggest_return_binding_for_missing_tail_expr( &self, err: &mut Diagnostic, expr: &hir::Expr<'_>, @@ -2050,7 +2056,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } - fn check_wrong_return_type_due_to_generic_arg( + fn note_wrong_return_ty_due_to_generic_arg( &self, err: &mut Diagnostic, expr: &hir::Expr<'_>, diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index 82fc1256bba64..898b2f79391ea 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -274,13 +274,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expected_ty_expr: Option<&'tcx hir::Expr<'tcx>>, ) -> bool { let expr = expr.peel_blocks(); - if let Some((sp, msg, suggestion, applicability, verbose, annotation)) = - self.check_ref(expr, found, expected) + if let Some((suggestion, msg, applicability, verbose, annotation)) = + self.suggest_deref_or_ref(expr, found, expected) { if verbose { - err.span_suggestion_verbose(sp, &msg, suggestion, applicability); + err.multipart_suggestion_verbose(&msg, suggestion, applicability); } else { - err.span_suggestion(sp, &msg, suggestion, applicability); + err.multipart_suggestion(&msg, suggestion, applicability); } if annotation { let suggest_annotation = match expr.peel_drop_temps().kind { @@ -342,7 +342,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err.span_label(sp, format!("{descr} `{name}` defined here")); } return true; - } else if self.check_for_cast(err, expr, found, expected, expected_ty_expr) { + } else if self.suggest_cast(err, expr, found, expected, expected_ty_expr) { return true; } else { let methods = self.get_conversion_methods(expr.span, expected, found, expr.hir_id); diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 43f40ada5acb6..ddeb0fab83ab6 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -1044,7 +1044,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ); } - self.check_for_inner_self(&mut err, source, rcvr_ty, item_name); + self.suggest_unwrapping_inner_self(&mut err, source, rcvr_ty, item_name); bound_spans.sort(); bound_spans.dedup(); @@ -1131,7 +1131,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } - self.check_for_deref_method(&mut err, source, rcvr_ty, item_name, expected); + self.note_derefed_ty_has_method(&mut err, source, rcvr_ty, item_name, expected); return Some(err); } @@ -1804,7 +1804,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } - fn check_for_inner_self( + fn suggest_unwrapping_inner_self( &self, err: &mut Diagnostic, source: SelfSource<'tcx>, @@ -2174,7 +2174,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } - fn check_for_deref_method( + fn note_derefed_ty_has_method( &self, err: &mut Diagnostic, self_source: SelfSource<'tcx>, diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py index 9c6c917ac4a2b..ff261ab983273 100644 --- a/src/bootstrap/bootstrap.py +++ b/src/bootstrap/bootstrap.py @@ -19,7 +19,10 @@ except ImportError: lzma = None -if sys.platform == 'win32': +def platform_is_win32(): + return sys.platform == 'win32' + +if platform_is_win32(): EXE_SUFFIX = ".exe" else: EXE_SUFFIX = "" @@ -78,7 +81,6 @@ def _download(path, url, probably_big, verbose, exception): if probably_big or verbose: print("downloading {}".format(url)) - platform_is_win32 = sys.platform == 'win32' try: if probably_big or verbose: option = "-#" @@ -86,7 +88,7 @@ def _download(path, url, probably_big, verbose, exception): option = "-s" # If curl is not present on Win32, we should not sys.exit # but raise `CalledProcessError` or `OSError` instead - require(["curl", "--version"], exception=platform_is_win32) + require(["curl", "--version"], exception=platform_is_win32()) with open(path, "wb") as outfile: run(["curl", option, "-L", # Follow redirect. @@ -99,8 +101,8 @@ def _download(path, url, probably_big, verbose, exception): ) except (subprocess.CalledProcessError, OSError, RuntimeError): # see http://serverfault.com/questions/301128/how-to-download - if platform_is_win32: - run(["PowerShell.exe", "/nologo", "-Command", + if platform_is_win32(): + run_powershell([ "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12;", "(New-Object System.Net.WebClient).DownloadFile('{}', '{}')".format(url, path)], verbose=verbose, @@ -174,6 +176,10 @@ def run(args, verbose=False, exception=False, is_bootstrap=False, **kwargs): else: sys.exit(err) +def run_powershell(script, *args, **kwargs): + """Run a powershell script""" + run(["PowerShell.exe", "/nologo", "-Command"] + script, *args, **kwargs) + def require(cmd, exit=True, exception=False): '''Run a command, returning its output. @@ -229,7 +235,7 @@ def default_build_triple(verbose): print("pre-installed rustc not detected: {}".format(e)) print("falling back to auto-detect") - required = sys.platform != 'win32' + required = not platform_is_win32() ostype = require(["uname", "-s"], exit=required) cputype = require(['uname', '-m'], exit=required) @@ -434,6 +440,23 @@ def download_toolchain(self): (not os.path.exists(self.rustc()) or self.program_out_of_date(self.rustc_stamp(), key)): if os.path.exists(bin_root): + # HACK: On Windows, we can't delete rust-analyzer-proc-macro-server while it's + # running. Kill it. + if platform_is_win32(): + print("Killing rust-analyzer-proc-macro-srv before deleting stage0 toolchain") + regex = '{}\\\\(host|{})\\\\stage0\\\\libexec'.format( + os.path.basename(self.build_dir), + self.build + ) + script = ( + # NOTE: can't use `taskkill` or `Get-Process -Name` because they error if + # the server isn't running. + 'Get-Process | ' + + 'Where-Object {$_.Name -eq "rust-analyzer-proc-macro-srv"} |' + + 'Where-Object {{$_.Path -match "{}"}} |'.format(regex) + + 'Stop-Process' + ) + run_powershell([script]) shutil.rmtree(bin_root) tarball_suffix = '.tar.gz' if lzma is None else '.tar.xz' filename = "rust-std-{}-{}{}".format( diff --git a/src/doc/rustdoc/src/lints.md b/src/doc/rustdoc/src/lints.md index 45db3bb9b007b..fd57b07964481 100644 --- a/src/doc/rustdoc/src/lints.md +++ b/src/doc/rustdoc/src/lints.md @@ -374,3 +374,41 @@ warning: this URL is not a hyperlink warning: 2 warnings emitted ``` + +## `unescaped_backticks` + +This lint is **allowed by default**. It detects backticks (\`) that are not escaped. +This usually means broken inline code. For example: + +```rust +#![warn(rustdoc::unescaped_backticks)] + +/// `add(a, b) is the same as `add(b, a)`. +pub fn add(a: i32, b: i32) -> i32 { a + b } +``` + +Which will give: + +```text +warning: unescaped backtick + --> src/lib.rs:3:41 + | +3 | /// `add(a, b) is the same as `add(b, a)`. + | ^ + | +note: the lint level is defined here + --> src/lib.rs:1:9 + | +1 | #![warn(rustdoc::unescaped_backticks)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: a previous inline code might be longer than expected + | +3 | /// `add(a, b)` is the same as `add(b, a)`. + | + +help: if you meant to use a literal backtick, escape it + | +3 | /// `add(a, b) is the same as `add(b, a)\`. + | + + +warning: 1 warning emitted +``` diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index a5f08fdac11c9..d90d0aecb93ad 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -1155,10 +1155,10 @@ fn render_assoc_items_inner( let (non_trait, traits): (Vec<_>, _) = v.iter().partition(|i| i.inner_impl().trait_.is_none()); if !non_trait.is_empty() { let mut tmp_buf = Buffer::html(); - let (render_mode, id) = match what { + let (render_mode, id, class_html) = match what { AssocItemRender::All => { write_impl_section_heading(&mut tmp_buf, "Implementations", "implementations"); - (RenderMode::Normal, "implementations-list".to_owned()) + (RenderMode::Normal, "implementations-list".to_owned(), "") } AssocItemRender::DerefFor { trait_, type_, deref_mut_ } => { let id = @@ -1175,7 +1175,11 @@ fn render_assoc_items_inner( ), &id, ); - (RenderMode::ForDeref { mut_: deref_mut_ }, cx.derive_id(id)) + ( + RenderMode::ForDeref { mut_: deref_mut_ }, + cx.derive_id(id), + r#" class="impl-items""#, + ) } }; let mut impls_buf = Buffer::html(); @@ -1199,7 +1203,7 @@ fn render_assoc_items_inner( } if !impls_buf.is_empty() { write!(w, "{}", tmp_buf.into_inner()).unwrap(); - write!(w, "
", id).unwrap(); + write!(w, "
").unwrap(); write!(w, "{}", impls_buf.into_inner()).unwrap(); w.write_str("
").unwrap(); } @@ -1788,12 +1792,14 @@ fn render_impl( .into_string() ); } + if !default_impl_items.is_empty() || !impl_items.is_empty() { + w.write_str("
"); + close_tags.insert_str(0, "
"); + } } if !default_impl_items.is_empty() || !impl_items.is_empty() { - w.write_str("
"); w.push_buffer(default_impl_items); w.push_buffer(impl_items); - close_tags.insert_str(0, "
"); } w.write_str(&close_tags); } diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index c15afca22611b..60754130d997c 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -7,14 +7,15 @@ #![feature(assert_matches)] #![feature(box_patterns)] #![feature(drain_filter)] +#![feature(impl_trait_in_assoc_type)] +#![feature(iter_intersperse)] +#![feature(lazy_cell)] #![feature(let_chains)] -#![feature(test)] #![feature(never_type)] -#![feature(lazy_cell)] -#![feature(type_ascription)] -#![feature(iter_intersperse)] +#![feature(round_char_boundary)] +#![feature(test)] #![feature(type_alias_impl_trait)] -#![feature(impl_trait_in_assoc_type)] +#![feature(type_ascription)] #![recursion_limit = "256"] #![warn(rustc::internal)] #![allow(clippy::collapsible_if, clippy::collapsible_else_if)] diff --git a/src/librustdoc/lint.rs b/src/librustdoc/lint.rs index 6d289eb996de7..749c1ff51bfc5 100644 --- a/src/librustdoc/lint.rs +++ b/src/librustdoc/lint.rs @@ -174,6 +174,17 @@ declare_rustdoc_lint! { "codeblock could not be parsed as valid Rust or is empty" } +declare_rustdoc_lint! { + /// The `unescaped_backticks` lint detects unescaped backticks (\`), which usually + /// mean broken inline code. This is a `rustdoc` only lint, see the documentation + /// in the [rustdoc book]. + /// + /// [rustdoc book]: ../../../rustdoc/lints.html#unescaped_backticks + UNESCAPED_BACKTICKS, + Allow, + "detects unescaped backticks in doc comments" +} + pub(crate) static RUSTDOC_LINTS: Lazy> = Lazy::new(|| { vec![ BROKEN_INTRA_DOC_LINKS, @@ -185,6 +196,7 @@ pub(crate) static RUSTDOC_LINTS: Lazy> = Lazy::new(|| { INVALID_HTML_TAGS, BARE_URLS, MISSING_CRATE_LEVEL_DOCS, + UNESCAPED_BACKTICKS, ] }); diff --git a/src/librustdoc/passes/lint.rs b/src/librustdoc/passes/lint.rs index 97031c4f028f4..e653207b9b6d4 100644 --- a/src/librustdoc/passes/lint.rs +++ b/src/librustdoc/passes/lint.rs @@ -4,6 +4,7 @@ mod bare_urls; mod check_code_block_syntax; mod html_tags; +mod unescaped_backticks; use super::Pass; use crate::clean::*; @@ -27,6 +28,7 @@ impl<'a, 'tcx> DocVisitor for Linter<'a, 'tcx> { bare_urls::visit_item(self.cx, item); check_code_block_syntax::visit_item(self.cx, item); html_tags::visit_item(self.cx, item); + unescaped_backticks::visit_item(self.cx, item); self.visit_item_recur(item) } diff --git a/src/librustdoc/passes/lint/unescaped_backticks.rs b/src/librustdoc/passes/lint/unescaped_backticks.rs new file mode 100644 index 0000000000000..33cef82a60cbb --- /dev/null +++ b/src/librustdoc/passes/lint/unescaped_backticks.rs @@ -0,0 +1,416 @@ +//! Detects unescaped backticks (\`) in doc comments. + +use crate::clean::Item; +use crate::core::DocContext; +use crate::html::markdown::main_body_opts; +use crate::passes::source_span_for_markdown_range; +use pulldown_cmark::{BrokenLink, Event, Parser}; +use rustc_errors::DiagnosticBuilder; +use rustc_lint_defs::Applicability; +use std::ops::Range; + +pub(crate) fn visit_item(cx: &DocContext<'_>, item: &Item) { + let tcx = cx.tcx; + let Some(hir_id) = DocContext::as_local_hir_id(tcx, item.item_id) else { + // If non-local, no need to check anything. + return; + }; + + let dox = item.attrs.collapsed_doc_value().unwrap_or_default(); + if dox.is_empty() { + return; + } + + let link_names = item.link_names(&cx.cache); + let mut replacer = |broken_link: BrokenLink<'_>| { + link_names + .iter() + .find(|link| *link.original_text == *broken_link.reference) + .map(|link| ((*link.href).into(), (*link.new_text).into())) + }; + let parser = Parser::new_with_broken_link_callback(&dox, main_body_opts(), Some(&mut replacer)) + .into_offset_iter(); + + let mut element_stack = Vec::new(); + + let mut prev_text_end = 0; + for (event, event_range) in parser { + match event { + Event::Start(_) => { + element_stack.push(Element::new(event_range)); + } + Event::End(_) => { + let element = element_stack.pop().unwrap(); + + let Some(backtick_index) = element.backtick_index else { + continue; + }; + + // If we can't get a span of the backtick, because it is in a `#[doc = ""]` attribute, + // use the span of the entire attribute as a fallback. + let span = source_span_for_markdown_range( + tcx, + &dox, + &(backtick_index..backtick_index + 1), + &item.attrs, + ) + .unwrap_or_else(|| item.attr_span(tcx)); + + cx.tcx.struct_span_lint_hir(crate::lint::UNESCAPED_BACKTICKS, hir_id, span, "unescaped backtick", |lint| { + let mut help_emitted = false; + + match element.prev_code_guess { + PrevCodeGuess::None => {} + PrevCodeGuess::Start { guess, .. } => { + // "foo` `bar`" -> "`foo` `bar`" + if let Some(suggest_index) = clamp_start(guess, &element.suggestible_ranges) + && can_suggest_backtick(&dox, suggest_index) + { + suggest_insertion(cx, item, &dox, lint, suggest_index, '`', "the opening backtick of a previous inline code may be missing"); + help_emitted = true; + } + } + PrevCodeGuess::End { guess, .. } => { + // "`foo `bar`" -> "`foo` `bar`" + // Don't `clamp_end` here, because the suggestion is guaranteed to be inside + // an inline code node and we intentionally "break" the inline code here. + let suggest_index = guess; + if can_suggest_backtick(&dox, suggest_index) { + suggest_insertion(cx, item, &dox, lint, suggest_index, '`', "a previous inline code might be longer than expected"); + help_emitted = true; + } + } + } + + if !element.prev_code_guess.is_confident() { + // "`foo` bar`" -> "`foo` `bar`" + if let Some(guess) = guess_start_of_code(&dox, element.element_range.start..backtick_index) + && let Some(suggest_index) = clamp_start(guess, &element.suggestible_ranges) + && can_suggest_backtick(&dox, suggest_index) + { + suggest_insertion(cx, item, &dox, lint, suggest_index, '`', "the opening backtick of an inline code may be missing"); + help_emitted = true; + } + + // "`foo` `bar" -> "`foo` `bar`" + // Don't suggest closing backtick after single trailing char, + // if we already suggested opening backtick. For example: + // "foo`." -> "`foo`." or "foo`s" -> "`foo`s". + if let Some(guess) = guess_end_of_code(&dox, backtick_index + 1..element.element_range.end) + && let Some(suggest_index) = clamp_end(guess, &element.suggestible_ranges) + && can_suggest_backtick(&dox, suggest_index) + && (!help_emitted || suggest_index - backtick_index > 2) + { + suggest_insertion(cx, item, &dox, lint, suggest_index, '`', "the closing backtick of an inline code may be missing"); + help_emitted = true; + } + } + + if !help_emitted { + lint.help("the opening or closing backtick of an inline code may be missing"); + } + + suggest_insertion(cx, item, &dox, lint, backtick_index, '\\', "if you meant to use a literal backtick, escape it"); + + lint + }); + } + Event::Code(_) => { + let element = element_stack + .last_mut() + .expect("expected inline code node to be inside of an element"); + assert!( + event_range.start >= element.element_range.start + && event_range.end <= element.element_range.end + ); + + // This inline code might be longer than it's supposed to be. + // Only check single backtick inline code for now. + if !element.prev_code_guess.is_confident() + && dox.as_bytes().get(event_range.start) == Some(&b'`') + && dox.as_bytes().get(event_range.start + 1) != Some(&b'`') + { + let range_inside = event_range.start + 1..event_range.end - 1; + let text_inside = &dox[range_inside.clone()]; + + let is_confident = text_inside.starts_with(char::is_whitespace) + || text_inside.ends_with(char::is_whitespace); + + if let Some(guess) = guess_end_of_code(&dox, range_inside) { + // Find earlier end of code. + element.prev_code_guess = PrevCodeGuess::End { guess, is_confident }; + } else { + // Find alternate start of code. + let range_before = element.element_range.start..event_range.start; + if let Some(guess) = guess_start_of_code(&dox, range_before) { + element.prev_code_guess = PrevCodeGuess::Start { guess, is_confident }; + } + } + } + } + Event::Text(text) => { + let element = element_stack + .last_mut() + .expect("expected inline text node to be inside of an element"); + assert!( + event_range.start >= element.element_range.start + && event_range.end <= element.element_range.end + ); + + // The first char is escaped if the prev char is \ and not part of a text node. + let is_escaped = prev_text_end < event_range.start + && dox.as_bytes()[event_range.start - 1] == b'\\'; + + // Don't lint backslash-escaped (\`) or html-escaped (`) backticks. + if *text == *"`" && !is_escaped && *text == dox[event_range.clone()] { + // We found a stray backtick. + assert!( + element.backtick_index.is_none(), + "expected at most one unescaped backtick per element", + ); + element.backtick_index = Some(event_range.start); + } + + prev_text_end = event_range.end; + + if is_escaped { + // Ensure that we suggest "`\x" and not "\`x". + element.suggestible_ranges.push(event_range.start - 1..event_range.end); + } else { + element.suggestible_ranges.push(event_range); + } + } + _ => {} + } + } +} + +/// A previous inline code node, that looks wrong. +/// +/// `guess` is the position, where we want to suggest a \` and the guess `is_confident` if an +/// inline code starts or ends with a whitespace. +#[derive(Debug)] +enum PrevCodeGuess { + None, + + /// Missing \` at start. + /// + /// ```markdown + /// foo` `bar` + /// ``` + Start { + guess: usize, + is_confident: bool, + }, + + /// Missing \` at end. + /// + /// ```markdown + /// `foo `bar` + /// ``` + End { + guess: usize, + is_confident: bool, + }, +} + +impl PrevCodeGuess { + fn is_confident(&self) -> bool { + match *self { + PrevCodeGuess::None => false, + PrevCodeGuess::Start { is_confident, .. } | PrevCodeGuess::End { is_confident, .. } => { + is_confident + } + } + } +} + +/// A markdown [tagged element], which may or may not contain an unescaped backtick. +/// +/// [tagged element]: https://docs.rs/pulldown-cmark/0.9/pulldown_cmark/enum.Tag.html +#[derive(Debug)] +struct Element { + /// The full range (span) of the element in the doc string. + element_range: Range, + + /// The ranges where we're allowed to put backticks. + /// This is used to prevent breaking markdown elements like links or lists. + suggestible_ranges: Vec>, + + /// The unescaped backtick. + backtick_index: Option, + + /// Suggest a different start or end of an inline code. + prev_code_guess: PrevCodeGuess, +} + +impl Element { + const fn new(element_range: Range) -> Self { + Self { + element_range, + suggestible_ranges: Vec::new(), + backtick_index: None, + prev_code_guess: PrevCodeGuess::None, + } + } +} + +/// Given a potentially unclosed inline code, attempt to find the start. +fn guess_start_of_code(dox: &str, range: Range) -> Option { + assert!(dox.as_bytes()[range.end] == b'`'); + + let mut braces = 0; + let mut guess = 0; + for (idx, ch) in dox[range.clone()].char_indices().rev() { + match ch { + ')' | ']' | '}' => braces += 1, + '(' | '[' | '{' => { + if braces == 0 { + guess = idx + 1; + break; + } + braces -= 1; + } + ch if ch.is_whitespace() && braces == 0 => { + guess = idx + 1; + break; + } + _ => (), + } + } + + guess += range.start; + + // Don't suggest empty inline code or duplicate backticks. + can_suggest_backtick(dox, guess).then_some(guess) +} + +/// Given a potentially unclosed inline code, attempt to find the end. +fn guess_end_of_code(dox: &str, range: Range) -> Option { + // Punctuation that should be outside of the inline code. + const TRAILING_PUNCTUATION: &[u8] = b".,"; + + assert!(dox.as_bytes()[range.start - 1] == b'`'); + + let text = dox[range.clone()].trim_end(); + let mut braces = 0; + let mut guess = text.len(); + for (idx, ch) in text.char_indices() { + match ch { + '(' | '[' | '{' => braces += 1, + ')' | ']' | '}' => { + if braces == 0 { + guess = idx; + break; + } + braces -= 1; + } + ch if ch.is_whitespace() && braces == 0 => { + guess = idx; + break; + } + _ => (), + } + } + + // Strip a single trailing punctuation. + if guess >= 1 + && TRAILING_PUNCTUATION.contains(&text.as_bytes()[guess - 1]) + && (guess < 2 || !TRAILING_PUNCTUATION.contains(&text.as_bytes()[guess - 2])) + { + guess -= 1; + } + + guess += range.start; + + // Don't suggest empty inline code or duplicate backticks. + can_suggest_backtick(dox, guess).then_some(guess) +} + +/// Returns whether inserting a backtick at `dox[index]` will not produce double backticks. +fn can_suggest_backtick(dox: &str, index: usize) -> bool { + (index == 0 || dox.as_bytes()[index - 1] != b'`') + && (index == dox.len() || dox.as_bytes()[index] != b'`') +} + +/// Increase the index until it is inside or one past the end of one of the ranges. +/// +/// The ranges must be sorted for this to work correctly. +fn clamp_start(index: usize, ranges: &[Range]) -> Option { + for range in ranges { + if range.start >= index { + return Some(range.start); + } + if index <= range.end { + return Some(index); + } + } + None +} + +/// Decrease the index until it is inside or one past the end of one of the ranges. +/// +/// The ranges must be sorted for this to work correctly. +fn clamp_end(index: usize, ranges: &[Range]) -> Option { + for range in ranges.iter().rev() { + if range.end <= index { + return Some(range.end); + } + if index >= range.start { + return Some(index); + } + } + None +} + +/// Try to emit a span suggestion and fall back to help messages if we can't find a suitable span. +/// +/// This helps finding backticks in huge macro-generated docs. +fn suggest_insertion( + cx: &DocContext<'_>, + item: &Item, + dox: &str, + lint: &mut DiagnosticBuilder<'_, ()>, + insert_index: usize, + suggestion: char, + message: &str, +) { + /// Maximum bytes of context to show around the insertion. + const CONTEXT_MAX_LEN: usize = 80; + + if let Some(span) = + source_span_for_markdown_range(cx.tcx, &dox, &(insert_index..insert_index), &item.attrs) + { + lint.span_suggestion(span, message, suggestion, Applicability::MaybeIncorrect); + } else { + let line_start = dox[..insert_index].rfind('\n').map_or(0, |idx| idx + 1); + let line_end = dox[insert_index..].find('\n').map_or(dox.len(), |idx| idx + insert_index); + + let context_before_max_len = if insert_index - line_start < CONTEXT_MAX_LEN / 2 { + insert_index - line_start + } else if line_end - insert_index < CONTEXT_MAX_LEN / 2 { + CONTEXT_MAX_LEN - (line_end - insert_index) + } else { + CONTEXT_MAX_LEN / 2 + }; + let context_after_max_len = CONTEXT_MAX_LEN - context_before_max_len; + + let (prefix, context_start) = if insert_index - line_start <= context_before_max_len { + ("", line_start) + } else { + ("...", dox.ceil_char_boundary(insert_index - context_before_max_len)) + }; + let (suffix, context_end) = if line_end - insert_index <= context_after_max_len { + ("", line_end) + } else { + ("...", dox.floor_char_boundary(insert_index + context_after_max_len)) + }; + + let context_full = &dox[context_start..context_end].trim_end(); + let context_before = &dox[context_start..insert_index]; + let context_after = &dox[insert_index..context_end].trim_end(); + lint.help(format!( + "{message}\n change: {prefix}{context_full}{suffix}\nto this: {prefix}{context_before}{suggestion}{context_after}{suffix}" + )); + } +} diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs index 01da5981015f9..8cc935e54d117 100644 --- a/src/tools/compiletest/src/header.rs +++ b/src/tools/compiletest/src/header.rs @@ -90,6 +90,9 @@ pub struct TestProps { pub unset_rustc_env: Vec, // Environment settings to use during execution pub exec_env: Vec<(String, String)>, + // Environment variables to unset prior to execution. + // Variables are unset before applying 'exec_env' + pub unset_exec_env: Vec, // Build documentation for all specified aux-builds as well pub build_aux_docs: bool, // Flag to force a crate to be built with the host architecture @@ -198,6 +201,7 @@ mod directives { pub const AUX_CRATE: &'static str = "aux-crate"; pub const EXEC_ENV: &'static str = "exec-env"; pub const RUSTC_ENV: &'static str = "rustc-env"; + pub const UNSET_EXEC_ENV: &'static str = "unset-exec-env"; pub const UNSET_RUSTC_ENV: &'static str = "unset-rustc-env"; pub const FORBID_OUTPUT: &'static str = "forbid-output"; pub const CHECK_TEST_LINE_NUMBERS_MATCH: &'static str = "check-test-line-numbers-match"; @@ -231,6 +235,7 @@ impl TestProps { rustc_env: vec![], unset_rustc_env: vec![], exec_env: vec![], + unset_exec_env: vec![], build_aux_docs: false, force_host: false, check_stdout: false, @@ -382,6 +387,12 @@ impl TestProps { &mut self.exec_env, Config::parse_env, ); + config.push_name_value_directive( + ln, + UNSET_EXEC_ENV, + &mut self.unset_exec_env, + |r| r, + ); config.push_name_value_directive( ln, RUSTC_ENV, diff --git a/src/tools/compiletest/src/header/cfg.rs b/src/tools/compiletest/src/header/cfg.rs index a9694d4d52c88..86a749b935d82 100644 --- a/src/tools/compiletest/src/header/cfg.rs +++ b/src/tools/compiletest/src/header/cfg.rs @@ -165,11 +165,15 @@ pub(super) fn parse_cfg_name_directive<'a>( message: "when the architecture is part of the Thumb family" } + // Technically the locally built compiler uses the "dev" channel rather than the "nightly" + // channel, even though most people don't know or won't care about it. To avoid confusion, we + // treat the "dev" channel as the "nightly" channel when processing the directive. condition! { - name: &config.channel, + name: if config.channel == "dev" { "nightly" } else { &config.channel }, allowed_names: &["stable", "beta", "nightly"], message: "when the release channel is {name}", } + condition! { name: "cross-compile", condition: config.target != config.host, diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index e03a73c4e713c..0fd9f3ae3f406 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -1614,8 +1614,13 @@ impl<'test> TestCx<'test> { test_client .args(&["run", &support_libs.len().to_string(), &prog]) .args(support_libs) - .args(args) - .envs(env.clone()); + .args(args); + + for key in &self.props.unset_exec_env { + test_client.env_remove(key); + } + test_client.envs(env.clone()); + self.compose_and_run( test_client, self.config.run_lib_path.to_str().unwrap(), @@ -1627,7 +1632,13 @@ impl<'test> TestCx<'test> { let aux_dir = self.aux_output_dir_name(); let ProcArgs { prog, args } = self.make_run_args(); let mut wr_run = Command::new("wr-run"); - wr_run.args(&[&prog]).args(args).envs(env.clone()); + wr_run.args(&[&prog]).args(args); + + for key in &self.props.unset_exec_env { + wr_run.env_remove(key); + } + wr_run.envs(env.clone()); + self.compose_and_run( wr_run, self.config.run_lib_path.to_str().unwrap(), @@ -1639,7 +1650,13 @@ impl<'test> TestCx<'test> { let aux_dir = self.aux_output_dir_name(); let ProcArgs { prog, args } = self.make_run_args(); let mut program = Command::new(&prog); - program.args(args).current_dir(&self.output_base_dir()).envs(env.clone()); + program.args(args).current_dir(&self.output_base_dir()); + + for key in &self.props.unset_exec_env { + program.env_remove(key); + } + program.envs(env.clone()); + self.compose_and_run( program, self.config.run_lib_path.to_str().unwrap(), diff --git a/tests/rustdoc-ui/unescaped_backticks.rs b/tests/rustdoc-ui/unescaped_backticks.rs new file mode 100644 index 0000000000000..f1ad7c8d4c784 --- /dev/null +++ b/tests/rustdoc-ui/unescaped_backticks.rs @@ -0,0 +1,342 @@ +#![deny(rustdoc::unescaped_backticks)] +#![allow(rustdoc::broken_intra_doc_links)] +#![allow(rustdoc::invalid_html_tags)] + +/// +pub fn empty() {} + +#[doc = ""] +pub fn empty2() {} + +/// ` +//~^ ERROR unescaped backtick +pub fn single() {} + +/// \` +pub fn escaped() {} + +/// \\` +//~^ ERROR unescaped backtick +pub fn not_escaped() {} + +/// \\\` +pub fn not_not_escaped() {} + +/// [`link1] +//~^ ERROR unescaped backtick +pub fn link1() {} + +/// [link2`] +//~^ ERROR unescaped backtick +pub fn link2() {} + +/// [`link_long](link_long) +//~^ ERROR unescaped backtick +pub fn link_long() {} + +/// [`broken-link] +//~^ ERROR unescaped backtick +pub fn broken_link() {} + +/// +pub fn url() {} + +/// +//~^ ERROR unescaped backtick +pub fn not_url() {} + +///

`

+pub fn html_tag() {} + +/// ` +pub fn html_escape() {} + +/// 🦀`🦀 +//~^ ERROR unescaped backtick +pub fn unicode() {} + +/// `foo( +//~^ ERROR unescaped backtick +/// +/// paragraph +pub fn paragraph() {} + +/// `foo `bar` +//~^ ERROR unescaped backtick +/// +/// paragraph +pub fn paragraph2() {} + +/// `foo( +//~^ ERROR unescaped backtick +/// not paragraph +pub fn not_paragraph() {} + +/// Addition is commutative, which means that add(a, b)` is the same as `add(b, a)`. +//~^ ERROR unescaped backtick +/// +/// You could use this function to add 42 to a number `n` (add(n, 42)`), +/// or even to add a number `n` to 42 (`add(42, b)`)! +//~^ ERROR unescaped backtick +pub fn add1(a: i32, b: i32) -> i32 { a + b } + +/// Addition is commutative, which means that `add(a, b) is the same as `add(b, a)`. +//~^ ERROR unescaped backtick +/// +/// You could use this function to add 42 to a number `n` (`add(n, 42)), +/// or even to add a number `n` to 42 (`add(42, n)`)! +//~^ ERROR unescaped backtick +pub fn add2(a: i32, b: i32) -> i32 { a + b } + +/// Addition is commutative, which means that `add(a, b)` is the same as add(b, a)`. +//~^ ERROR unescaped backtick +/// +/// You could use this function to add 42 to a number `n` (`add(n, 42)`), +/// or even to add a number `n` to 42 (add(42, n)`)! +//~^ ERROR unescaped backtick +pub fn add3(a: i32, b: i32) -> i32 { a + b } + +/// Addition is commutative, which means that `add(a, b)` is the same as `add(b, a). +//~^ ERROR unescaped backtick +/// +/// You could use this function to add 42 to a number `n` (`add(n, 42)), +/// or even to add a number `n` to 42 (`add(42, n)`)! +//~^ ERROR unescaped backtick +pub fn add4(a: i32, b: i32) -> i32 { a + b } + +#[doc = "`"] +//~^ ERROR unescaped backtick +pub fn attr() {} + +#[doc = concat!("\\", "`")] +pub fn attr_escaped() {} + +#[doc = concat!("\\\\", "`")] +//~^ ERROR unescaped backtick +pub fn attr_not_escaped() {} + +#[doc = "Addition is commutative, which means that add(a, b)` is the same as `add(b, a)`."] +//~^ ERROR unescaped backtick +pub fn attr_add1(a: i32, b: i32) -> i32 { a + b } + +#[doc = "Addition is commutative, which means that `add(a, b) is the same as `add(b, a)`."] +//~^ ERROR unescaped backtick +pub fn attr_add2(a: i32, b: i32) -> i32 { a + b } + +#[doc = "Addition is commutative, which means that `add(a, b)` is the same as add(b, a)`."] +//~^ ERROR unescaped backtick +pub fn attr_add3(a: i32, b: i32) -> i32 { a + b } + +#[doc = "Addition is commutative, which means that `add(a, b)` is the same as `add(b, a)."] +//~^ ERROR unescaped backtick +pub fn attr_add4(a: i32, b: i32) -> i32 { a + b } + +/// ``double backticks`` +/// `foo +//~^ ERROR unescaped backtick +pub fn double_backticks() {} + +/// # `(heading +//~^ ERROR unescaped backtick +/// ## heading2)` +//~^ ERROR unescaped backtick +/// +/// multi `( +//~^ ERROR unescaped backtick +/// line +/// ) heading +/// = +/// +/// para)`(graph +//~^ ERROR unescaped backtick +/// +/// para)`(graph2 +//~^ ERROR unescaped backtick +/// +/// 1. foo)` +//~^ ERROR unescaped backtick +/// 2. `(bar +//~^ ERROR unescaped backtick +/// * baz)` +//~^ ERROR unescaped backtick +/// * `(quux +//~^ ERROR unescaped backtick +/// +/// `#![this_is_actually_an_image(and(not), an = "attribute")] +//~^ ERROR unescaped backtick +/// +/// #![this_is_actually_an_image(and(not), an = "attribute")]` +//~^ ERROR unescaped backtick +/// +/// [this_is_actually_an_image(and(not), an = "attribute")]: `.png +/// +/// | `table( | )head` | +//~^ ERROR unescaped backtick +//~| ERROR unescaped backtick +/// |---------|--------| +/// | table`( | )`body | +//~^ ERROR unescaped backtick +//~| ERROR unescaped backtick +pub fn complicated_markdown() {} + +/// The `custom_mir` attribute tells the compiler to treat the function as being custom MIR. This +/// attribute only works on functions - there is no way to insert custom MIR into the middle of +/// another function. The `dialect` and `phase` parameters indicate which [version of MIR][dialect +/// docs] you are inserting here. Generally you'll want to use `#![custom_mir(dialect = "built")]` +/// if you want your MIR to be modified by the full MIR pipeline, or `#![custom_mir(dialect = +//~^ ERROR unescaped backtick +/// "runtime", phase = "optimized")] if you don't. +pub mod mir {} + +pub mod rustc { + /// Constructs a `TyKind::Error` type and registers a `delay_span_bug` with the given `msg to + //~^ ERROR unescaped backtick + /// ensure it gets used. + pub fn ty_error_with_message() {} + + pub struct WhereClause { + /// `true` if we ate a `where` token: this can happen + /// if we parsed no predicates (e.g. `struct Foo where {} + /// This allows us to accurately pretty-print + /// in `nt_to_tokenstream` + //~^ ERROR unescaped backtick + pub has_where_token: bool, + } + + /// A symbol is an interned or gensymed string. The use of `newtype_index!` means + /// that `Option` only takes up 4 bytes, because `newtype_index! reserves + //~^ ERROR unescaped backtick + /// the last 256 values for tagging purposes. + pub struct Symbol(); + + /// It is equivalent to `OpenOptions::new()` but allows you to write more + /// readable code. Instead of `OpenOptions::new().read(true).open("foo.txt")` + /// you can write `File::with_options().read(true).open("foo.txt"). This + /// also avoids the need to import `OpenOptions`. + //~^ ERROR unescaped backtick + pub fn with_options() {} + + /// Subtracts `set from `row`. `set` can be either `BitSet` or + /// `HybridBitSet`. Has no effect if `row` does not exist. + //~^ ERROR unescaped backtick + /// + /// Returns true if the row was changed. + pub fn subtract_row() {} + + pub mod assert_module_sources { + //! The reason that we use `cfg=...` and not `#[cfg_attr]` is so that + //! the HIR doesn't change as a result of the annotations, which might + //! perturb the reuse results. + //! + //! `#![rustc_expected_cgu_reuse(module="spike", cfg="rpass2", kind="post-lto")] + //~^ ERROR unescaped backtick + //! allows for doing a more fine-grained check to see if pre- or post-lto data + //! was re-used. + + /// `cfg=... + //~^ ERROR unescaped backtick + pub fn foo() {} + + /// `cfg=... and not `#[cfg_attr]` + //~^ ERROR unescaped backtick + pub fn bar() {} + } + + /// Conceptually, this is like a `Vec>`. But the number of + /// RWU`s can get very large, so it uses a more compact representation. + //~^ ERROR unescaped backtick + pub struct RWUTable {} + + /// Like [Self::canonicalize_query], but preserves distinct universes. For + /// example, canonicalizing `&'?0: Trait<'?1>`, where `'?0` is in `U1` and + /// `'?1` is in `U3` would be canonicalized to have ?0` in `U1` and `'?1` + /// in `U2`. + //~^ ERROR unescaped backtick + /// + /// This is used for Chalk integration. + pub fn canonicalize_query_preserving_universes() {} + + /// Note that we used to return `Error` here, but that was quite + /// dubious -- the premise was that an error would *eventually* be + /// reported, when the obligation was processed. But in general once + /// you see an `Error` you are supposed to be able to assume that an + /// error *has been* reported, so that you can take whatever heuristic + /// paths you want to take. To make things worse, it was possible for + /// cycles to arise, where you basically had a setup like ` + /// as Trait>::Foo == $0`. Here, normalizing ` as + /// Trait>::Foo> to `[type error]` would lead to an obligation of + /// ` as Trait>::Foo`. We are supposed to report + /// an error for this obligation, but we legitimately should not, + /// because it contains `[type error]`. Yuck! (See issue #29857 for + //~^ ERROR unescaped backtick + /// one case where this arose.) + pub fn normalize_to_error() {} + + /// you don't want to cache that `B: AutoTrait` or `A: AutoTrait` + /// is `EvaluatedToOk`; this is because they were only considered + /// ok on the premise that if `A: AutoTrait` held, but we indeed + /// encountered a problem (later on) with `A: AutoTrait. So we + /// currently set a flag on the stack node for `B: AutoTrait` (as + /// well as the second instance of `A: AutoTrait`) to suppress + //~^ ERROR unescaped backtick + /// caching. + pub struct TraitObligationStack; + + /// Extend `scc` so that it can outlive some placeholder region + /// from a universe it can't name; at present, the only way for + /// this to be true is if `scc` outlives `'static`. This is + /// actually stricter than necessary: ideally, we'd support bounds + /// like `for<'a: 'b`>` that might then allow us to approximate + /// `'a` with `'b` and not `'static`. But it will have to do for + //~^ ERROR unescaped backtick + /// now. + pub fn add_incompatible_universe(){} +} + +/// The Subscriber` may be accessed by calling [`WeakDispatch::upgrade`], +/// which returns an `Option`. If all [`Dispatch`] clones that point +/// at the `Subscriber` have been dropped, [`WeakDispatch::upgrade`] will return +/// `None`. Otherwise, it will return `Some(Dispatch)`. +//~^ ERROR unescaped backtick +/// +/// Returns some reference to this `[`Subscriber`] value if it is of type `T`, +/// or `None` if it isn't. +//~^ ERROR unescaped backtick +/// +/// Called before the filtered [`Layer]'s [`on_event`], to determine if +/// `on_event` should be called. +//~^ ERROR unescaped backtick +/// +/// Therefore, if the `Filter will change the value returned by this +/// method, it is responsible for ensuring that +/// [`rebuild_interest_cache`][rebuild] is called after the value of the max +//~^ ERROR unescaped backtick +/// level changes. +pub mod tracing {} + +macro_rules! id { + ($($tt:tt)*) => { $($tt)* } +} + +id! { + /// The Subscriber` may be accessed by calling [`WeakDispatch::upgrade`], + //~^ ERROR unescaped backtick + //~| ERROR unescaped backtick + //~| ERROR unescaped backtick + //~| ERROR unescaped backtick + /// which returns an `Option`. If all [`Dispatch`] clones that point + /// at the `Subscriber` have been dropped, [`WeakDispatch::upgrade`] will return + /// `None`. Otherwise, it will return `Some(Dispatch)`. + /// + /// Returns some reference to this `[`Subscriber`] value if it is of type `T`, + /// or `None` if it isn't. + /// + /// Called before the filtered [`Layer]'s [`on_event`], to determine if + /// `on_event` should be called. + /// + /// Therefore, if the `Filter will change the value returned by this + /// method, it is responsible for ensuring that + /// [`rebuild_interest_cache`][rebuild] is called after the value of the max + /// level changes. + pub mod tracing_macro {} +} diff --git a/tests/rustdoc-ui/unescaped_backticks.stderr b/tests/rustdoc-ui/unescaped_backticks.stderr new file mode 100644 index 0000000000000..e629dbc34e9b4 --- /dev/null +++ b/tests/rustdoc-ui/unescaped_backticks.stderr @@ -0,0 +1,959 @@ +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:186:70 + | +LL | /// if you want your MIR to be modified by the full MIR pipeline, or `#![custom_mir(dialect = + | ^ + | +note: the lint level is defined here + --> $DIR/unescaped_backticks.rs:1:9 + | +LL | #![deny(rustdoc::unescaped_backticks)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: the closing backtick of an inline code may be missing + | +LL | /// "runtime", phase = "optimized")]` if you don't. + | + +help: if you meant to use a literal backtick, escape it + | +LL | /// if you want your MIR to be modified by the full MIR pipeline, or \`#![custom_mir(dialect = + | + + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:231:13 + | +LL | //! `#![rustc_expected_cgu_reuse(module="spike", cfg="rpass2", kind="post-lto")] + | ^ + | +help: the closing backtick of an inline code may be missing + | +LL | //! `#![rustc_expected_cgu_reuse(module="spike", cfg="rpass2", kind="post-lto")]` + | + +help: if you meant to use a literal backtick, escape it + | +LL | //! \`#![rustc_expected_cgu_reuse(module="spike", cfg="rpass2", kind="post-lto")] + | + + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:236:13 + | +LL | /// `cfg=... + | ^ + | +help: the closing backtick of an inline code may be missing + | +LL | /// `cfg=...` + | + +help: if you meant to use a literal backtick, escape it + | +LL | /// \`cfg=... + | + + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:240:42 + | +LL | /// `cfg=... and not `#[cfg_attr]` + | ^ + | +help: a previous inline code might be longer than expected + | +LL | /// `cfg=...` and not `#[cfg_attr]` + | + +help: if you meant to use a literal backtick, escape it + | +LL | /// `cfg=... and not `#[cfg_attr]\` + | + + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:192:91 + | +LL | /// Constructs a `TyKind::Error` type and registers a `delay_span_bug` with the given `msg to + | ^ + | +help: the closing backtick of an inline code may be missing + | +LL | /// Constructs a `TyKind::Error` type and registers a `delay_span_bug` with the given `msg` to + | + +help: if you meant to use a literal backtick, escape it + | +LL | /// Constructs a `TyKind::Error` type and registers a `delay_span_bug` with the given \`msg to + | + + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:201:34 + | +LL | /// in `nt_to_tokenstream` + | ^ + | +help: a previous inline code might be longer than expected + | +LL | /// if we parsed no predicates (e.g. `struct` Foo where {} + | + +help: if you meant to use a literal backtick, escape it + | +LL | /// in `nt_to_tokenstream\` + | + + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:207:62 + | +LL | /// that `Option` only takes up 4 bytes, because `newtype_index! reserves + | ^ + | +help: the closing backtick of an inline code may be missing + | +LL | /// that `Option` only takes up 4 bytes, because `newtype_index!` reserves + | + +help: if you meant to use a literal backtick, escape it + | +LL | /// that `Option` only takes up 4 bytes, because \`newtype_index! reserves + | + + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:215:52 + | +LL | /// also avoids the need to import `OpenOptions`. + | ^ + | +help: a previous inline code might be longer than expected + | +LL | /// you can write `File::with_options().read(true).open("foo.txt")`. This + | + +help: if you meant to use a literal backtick, escape it + | +LL | /// also avoids the need to import `OpenOptions\`. + | + + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:220:46 + | +LL | /// `HybridBitSet`. Has no effect if `row` does not exist. + | ^ + | +help: a previous inline code might be longer than expected + | +LL | /// Subtracts `set` from `row`. `set` can be either `BitSet` or + | + +help: if you meant to use a literal backtick, escape it + | +LL | /// `HybridBitSet`. Has no effect if `row\` does not exist. + | + + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:246:12 + | +LL | /// RWU`s can get very large, so it uses a more compact representation. + | ^ + | +help: the opening backtick of an inline code may be missing + | +LL | /// `RWU`s can get very large, so it uses a more compact representation. + | + +help: if you meant to use a literal backtick, escape it + | +LL | /// RWU\`s can get very large, so it uses a more compact representation. + | + + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:253:15 + | +LL | /// in `U2`. + | ^ + | +help: the opening backtick of a previous inline code may be missing + | +LL | /// `'?1` is in `U3` would be canonicalized to have `?0` in `U1` and `'?1` + | + +help: if you meant to use a literal backtick, escape it + | +LL | /// in `U2\`. + | + + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:270:42 + | +LL | /// because it contains `[type error]`. Yuck! (See issue #29857 for + | ^ + | +help: a previous inline code might be longer than expected + | +LL | /// as Trait>::Foo == $0`. Here, normalizing `` as + | + +help: if you meant to use a literal backtick, escape it + | +LL | /// because it contains `[type error]\`. Yuck! (See issue #29857 for + | + + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:280:53 + | +LL | /// well as the second instance of `A: AutoTrait`) to suppress + | ^ + | +help: a previous inline code might be longer than expected + | +LL | /// encountered a problem (later on) with `A:` AutoTrait. So we + | + +help: if you meant to use a literal backtick, escape it + | +LL | /// well as the second instance of `A: AutoTrait\`) to suppress + | + + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:290:40 + | +LL | /// `'a` with `'b` and not `'static`. But it will have to do for + | ^ + | + = help: the opening or closing backtick of an inline code may be missing +help: if you meant to use a literal backtick, escape it + | +LL | /// `'a` with `'b` and not `'static\`. But it will have to do for + | + + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:299:54 + | +LL | /// `None`. Otherwise, it will return `Some(Dispatch)`. + | ^ + | +help: the opening backtick of a previous inline code may be missing + | +LL | /// The `Subscriber` may be accessed by calling [`WeakDispatch::upgrade`], + | + +help: if you meant to use a literal backtick, escape it + | +LL | /// `None`. Otherwise, it will return `Some(Dispatch)\`. + | + + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:303:13 + | +LL | /// or `None` if it isn't. + | ^ + | + = help: the opening or closing backtick of an inline code may be missing +help: if you meant to use a literal backtick, escape it + | +LL | /// or `None\` if it isn't. + | + + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:307:14 + | +LL | /// `on_event` should be called. + | ^ + | +help: a previous inline code might be longer than expected + | +LL | /// Called before the filtered [`Layer`]'s [`on_event`], to determine if + | + +help: if you meant to use a literal backtick, escape it + | +LL | /// `on_event\` should be called. + | + + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:312:29 + | +LL | /// [`rebuild_interest_cache`][rebuild] is called after the value of the max + | ^ + | +help: a previous inline code might be longer than expected + | +LL | /// Therefore, if the `Filter` will change the value returned by this + | + +help: if you meant to use a literal backtick, escape it + | +LL | /// [`rebuild_interest_cache\`][rebuild] is called after the value of the max + | + + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:322:5 + | +LL | / /// The Subscriber` may be accessed by calling [`WeakDispatch::upgrade`], +LL | | +LL | | +LL | | +... | +LL | | /// [`rebuild_interest_cache`][rebuild] is called after the value of the max +LL | | /// level changes. + | |______________________^ + | + = help: the opening backtick of a previous inline code may be missing + change: The Subscriber` may be accessed by calling [`WeakDispatch::upgrade`], + to this: The `Subscriber` may be accessed by calling [`WeakDispatch::upgrade`], + = help: if you meant to use a literal backtick, escape it + change: `None`. Otherwise, it will return `Some(Dispatch)`. + to this: `None`. Otherwise, it will return `Some(Dispatch)\`. + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:322:5 + | +LL | / /// The Subscriber` may be accessed by calling [`WeakDispatch::upgrade`], +LL | | +LL | | +LL | | +... | +LL | | /// [`rebuild_interest_cache`][rebuild] is called after the value of the max +LL | | /// level changes. + | |______________________^ + | + = help: the opening or closing backtick of an inline code may be missing + = help: if you meant to use a literal backtick, escape it + change: or `None` if it isn't. + to this: or `None\` if it isn't. + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:322:5 + | +LL | / /// The Subscriber` may be accessed by calling [`WeakDispatch::upgrade`], +LL | | +LL | | +LL | | +... | +LL | | /// [`rebuild_interest_cache`][rebuild] is called after the value of the max +LL | | /// level changes. + | |______________________^ + | + = help: a previous inline code might be longer than expected + change: Called before the filtered [`Layer]'s [`on_event`], to determine if + to this: Called before the filtered [`Layer`]'s [`on_event`], to determine if + = help: if you meant to use a literal backtick, escape it + change: `on_event` should be called. + to this: `on_event\` should be called. + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:322:5 + | +LL | / /// The Subscriber` may be accessed by calling [`WeakDispatch::upgrade`], +LL | | +LL | | +LL | | +... | +LL | | /// [`rebuild_interest_cache`][rebuild] is called after the value of the max +LL | | /// level changes. + | |______________________^ + | + = help: a previous inline code might be longer than expected + change: Therefore, if the `Filter will change the value returned by this + to this: Therefore, if the `Filter` will change the value returned by this + = help: if you meant to use a literal backtick, escape it + change: [`rebuild_interest_cache`][rebuild] is called after the value of the max + to this: [`rebuild_interest_cache\`][rebuild] is called after the value of the max + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:11:5 + | +LL | /// ` + | ^ + | + = help: the opening or closing backtick of an inline code may be missing +help: if you meant to use a literal backtick, escape it + | +LL | /// \` + | + + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:18:7 + | +LL | /// \` + | ^ + | +help: the opening backtick of an inline code may be missing + | +LL | /// `\` + | + +help: if you meant to use a literal backtick, escape it + | +LL | /// \\` + | + + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:25:6 + | +LL | /// [`link1] + | ^ + | +help: the closing backtick of an inline code may be missing + | +LL | /// [`link1`] + | + +help: if you meant to use a literal backtick, escape it + | +LL | /// [\`link1] + | + + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:29:11 + | +LL | /// [link2`] + | ^ + | +help: the opening backtick of an inline code may be missing + | +LL | /// [`link2`] + | + +help: if you meant to use a literal backtick, escape it + | +LL | /// [link2\`] + | + + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:33:6 + | +LL | /// [`link_long](link_long) + | ^ + | +help: the closing backtick of an inline code may be missing + | +LL | /// [`link_long`](link_long) + | + +help: if you meant to use a literal backtick, escape it + | +LL | /// [\`link_long](link_long) + | + + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:37:6 + | +LL | /// [`broken-link] + | ^ + | +help: the closing backtick of an inline code may be missing + | +LL | /// [`broken-link`] + | + +help: if you meant to use a literal backtick, escape it + | +LL | /// [\`broken-link] + | + + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:44:8 + | +LL | /// + | ^ + | +help: the opening backtick of an inline code may be missing + | +LL | /// ` + | + +help: if you meant to use a literal backtick, escape it + | +LL | /// + | + + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:54:6 + | +LL | /// 🦀`🦀 + | ^ + | +help: the opening backtick of an inline code may be missing + | +LL | /// `🦀`🦀 + | + +help: the closing backtick of an inline code may be missing + | +LL | /// 🦀`🦀` + | + +help: if you meant to use a literal backtick, escape it + | +LL | /// 🦀\`🦀 + | + + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:58:5 + | +LL | /// `foo( + | ^ + | +help: the closing backtick of an inline code may be missing + | +LL | /// `foo(` + | + +help: if you meant to use a literal backtick, escape it + | +LL | /// \`foo( + | + + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:64:14 + | +LL | /// `foo `bar` + | ^ + | +help: a previous inline code might be longer than expected + | +LL | /// `foo` `bar` + | + +help: if you meant to use a literal backtick, escape it + | +LL | /// `foo `bar\` + | + + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:70:5 + | +LL | /// `foo( + | ^ + | +help: the closing backtick of an inline code may be missing + | +LL | /// not paragraph` + | + +help: if you meant to use a literal backtick, escape it + | +LL | /// \`foo( + | + + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:75:83 + | +LL | /// Addition is commutative, which means that add(a, b)` is the same as `add(b, a)`. + | ^ + | +help: the opening backtick of a previous inline code may be missing + | +LL | /// Addition is commutative, which means that `add(a, b)` is the same as `add(b, a)`. + | + +help: if you meant to use a literal backtick, escape it + | +LL | /// Addition is commutative, which means that add(a, b)` is the same as `add(b, a)\`. + | + + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:79:51 + | +LL | /// or even to add a number `n` to 42 (`add(42, b)`)! + | ^ + | +help: the opening backtick of a previous inline code may be missing + | +LL | /// You could use this function to add 42 to a number `n` (`add(n, 42)`), + | + +help: if you meant to use a literal backtick, escape it + | +LL | /// or even to add a number `n` to 42 (`add(42, b)\`)! + | + + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:83:83 + | +LL | /// Addition is commutative, which means that `add(a, b) is the same as `add(b, a)`. + | ^ + | +help: a previous inline code might be longer than expected + | +LL | /// Addition is commutative, which means that `add(a, b)` is the same as `add(b, a)`. + | + +help: if you meant to use a literal backtick, escape it + | +LL | /// Addition is commutative, which means that `add(a, b) is the same as `add(b, a)\`. + | + + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:87:51 + | +LL | /// or even to add a number `n` to 42 (`add(42, n)`)! + | ^ + | +help: a previous inline code might be longer than expected + | +LL | /// You could use this function to add 42 to a number `n` (`add(n, 42)`), + | + +help: if you meant to use a literal backtick, escape it + | +LL | /// or even to add a number `n` to 42 (`add(42, n)\`)! + | + + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:91:83 + | +LL | /// Addition is commutative, which means that `add(a, b)` is the same as add(b, a)`. + | ^ + | +help: the opening backtick of an inline code may be missing + | +LL | /// Addition is commutative, which means that `add(a, b)` is the same as `add(b, a)`. + | + +help: if you meant to use a literal backtick, escape it + | +LL | /// Addition is commutative, which means that `add(a, b)` is the same as add(b, a)\`. + | + + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:95:50 + | +LL | /// or even to add a number `n` to 42 (add(42, n)`)! + | ^ + | +help: the opening backtick of an inline code may be missing + | +LL | /// or even to add a number `n` to 42 (`add(42, n)`)! + | + +help: if you meant to use a literal backtick, escape it + | +LL | /// or even to add a number `n` to 42 (add(42, n)\`)! + | + + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:99:74 + | +LL | /// Addition is commutative, which means that `add(a, b)` is the same as `add(b, a). + | ^ + | +help: the closing backtick of an inline code may be missing + | +LL | /// Addition is commutative, which means that `add(a, b)` is the same as `add(b, a)`. + | + +help: if you meant to use a literal backtick, escape it + | +LL | /// Addition is commutative, which means that `add(a, b)` is the same as \`add(b, a). + | + + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:103:51 + | +LL | /// or even to add a number `n` to 42 (`add(42, n)`)! + | ^ + | +help: a previous inline code might be longer than expected + | +LL | /// You could use this function to add 42 to a number `n` (`add(n, 42)`), + | + +help: if you meant to use a literal backtick, escape it + | +LL | /// or even to add a number `n` to 42 (`add(42, n)\`)! + | + + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:107:1 + | +LL | #[doc = "`"] + | ^^^^^^^^^^^^ + | + = help: the opening or closing backtick of an inline code may be missing + = help: if you meant to use a literal backtick, escape it + change: ` + to this: \` + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:114:1 + | +LL | #[doc = concat!("\\", "`")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: the opening backtick of an inline code may be missing + change: \` + to this: `\` + = help: if you meant to use a literal backtick, escape it + change: \` + to this: \\` + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:118:1 + | +LL | #[doc = "Addition is commutative, which means that add(a, b)` is the same as `add(b, a)`."] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: the opening backtick of a previous inline code may be missing + change: Addition is commutative, which means that add(a, b)` is the same as `add(b, a)`. + to this: Addition is commutative, which means that `add(a, b)` is the same as `add(b, a)`. + = help: if you meant to use a literal backtick, escape it + change: Addition is commutative, which means that add(a, b)` is the same as `add(b, a)`. + to this: Addition is commutative, which means that add(a, b)` is the same as `add(b, a)\`. + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:122:1 + | +LL | #[doc = "Addition is commutative, which means that `add(a, b) is the same as `add(b, a)`."] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: a previous inline code might be longer than expected + change: Addition is commutative, which means that `add(a, b) is the same as `add(b, a)`. + to this: Addition is commutative, which means that `add(a, b)` is the same as `add(b, a)`. + = help: if you meant to use a literal backtick, escape it + change: Addition is commutative, which means that `add(a, b) is the same as `add(b, a)`. + to this: Addition is commutative, which means that `add(a, b) is the same as `add(b, a)\`. + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:126:1 + | +LL | #[doc = "Addition is commutative, which means that `add(a, b)` is the same as add(b, a)`."] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: the opening backtick of an inline code may be missing + change: Addition is commutative, which means that `add(a, b)` is the same as add(b, a)`. + to this: Addition is commutative, which means that `add(a, b)` is the same as `add(b, a)`. + = help: if you meant to use a literal backtick, escape it + change: Addition is commutative, which means that `add(a, b)` is the same as add(b, a)`. + to this: Addition is commutative, which means that `add(a, b)` is the same as add(b, a)\`. + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:130:1 + | +LL | #[doc = "Addition is commutative, which means that `add(a, b)` is the same as `add(b, a)."] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: the closing backtick of an inline code may be missing + change: Addition is commutative, which means that `add(a, b)` is the same as `add(b, a). + to this: Addition is commutative, which means that `add(a, b)` is the same as `add(b, a)`. + = help: if you meant to use a literal backtick, escape it + change: Addition is commutative, which means that `add(a, b)` is the same as `add(b, a). + to this: Addition is commutative, which means that `add(a, b)` is the same as \`add(b, a). + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:135:5 + | +LL | /// `foo + | ^ + | +help: the closing backtick of an inline code may be missing + | +LL | /// `foo` + | + +help: if you meant to use a literal backtick, escape it + | +LL | /// \`foo + | + + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:139:7 + | +LL | /// # `(heading + | ^ + | +help: the closing backtick of an inline code may be missing + | +LL | /// # `(heading` + | + +help: if you meant to use a literal backtick, escape it + | +LL | /// # \`(heading + | + + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:141:17 + | +LL | /// ## heading2)` + | ^ + | +help: the opening backtick of an inline code may be missing + | +LL | /// ## `heading2)` + | + +help: if you meant to use a literal backtick, escape it + | +LL | /// ## heading2)\` + | + + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:144:11 + | +LL | /// multi `( + | ^ + | +help: the closing backtick of an inline code may be missing + | +LL | /// )` heading + | + +help: if you meant to use a literal backtick, escape it + | +LL | /// multi \`( + | + + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:150:10 + | +LL | /// para)`(graph + | ^ + | +help: the opening backtick of an inline code may be missing + | +LL | /// `para)`(graph + | + +help: the closing backtick of an inline code may be missing + | +LL | /// para)`(graph` + | + +help: if you meant to use a literal backtick, escape it + | +LL | /// para)\`(graph + | + + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:153:10 + | +LL | /// para)`(graph2 + | ^ + | +help: the opening backtick of an inline code may be missing + | +LL | /// `para)`(graph2 + | + +help: the closing backtick of an inline code may be missing + | +LL | /// para)`(graph2` + | + +help: if you meant to use a literal backtick, escape it + | +LL | /// para)\`(graph2 + | + + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:156:12 + | +LL | /// 1. foo)` + | ^ + | +help: the opening backtick of an inline code may be missing + | +LL | /// 1. `foo)` + | + +help: if you meant to use a literal backtick, escape it + | +LL | /// 1. foo)\` + | + + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:158:8 + | +LL | /// 2. `(bar + | ^ + | +help: the closing backtick of an inline code may be missing + | +LL | /// 2. `(bar` + | + +help: if you meant to use a literal backtick, escape it + | +LL | /// 2. \`(bar + | + + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:160:11 + | +LL | /// * baz)` + | ^ + | +help: the opening backtick of an inline code may be missing + | +LL | /// * `baz)` + | + +help: if you meant to use a literal backtick, escape it + | +LL | /// * baz)\` + | + + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:162:7 + | +LL | /// * `(quux + | ^ + | +help: the closing backtick of an inline code may be missing + | +LL | /// * `(quux` + | + +help: if you meant to use a literal backtick, escape it + | +LL | /// * \`(quux + | + + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:165:5 + | +LL | /// `#![this_is_actually_an_image(and(not), an = "attribute")] + | ^ + | +help: the closing backtick of an inline code may be missing + | +LL | /// `#`![this_is_actually_an_image(and(not), an = "attribute")] + | + +help: if you meant to use a literal backtick, escape it + | +LL | /// \`#![this_is_actually_an_image(and(not), an = "attribute")] + | + + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:168:62 + | +LL | /// #![this_is_actually_an_image(and(not), an = "attribute")]` + | ^ + | +help: the opening backtick of an inline code may be missing + | +LL | /// `#![this_is_actually_an_image(and(not), an = "attribute")]` + | + +help: if you meant to use a literal backtick, escape it + | +LL | /// #![this_is_actually_an_image(and(not), an = "attribute")]\` + | + + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:173:7 + | +LL | /// | `table( | )head` | + | ^ + | +help: the closing backtick of an inline code may be missing + | +LL | /// | `table(` | )head` | + | + +help: if you meant to use a literal backtick, escape it + | +LL | /// | \`table( | )head` | + | + + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:173:22 + | +LL | /// | `table( | )head` | + | ^ + | +help: the opening backtick of an inline code may be missing + | +LL | /// | `table( | `)head` | + | + +help: if you meant to use a literal backtick, escape it + | +LL | /// | `table( | )head\` | + | + + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:177:12 + | +LL | /// | table`( | )`body | + | ^ + | +help: the opening backtick of an inline code may be missing + | +LL | /// | `table`( | )`body | + | + +help: if you meant to use a literal backtick, escape it + | +LL | /// | table\`( | )`body | + | + + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:177:18 + | +LL | /// | table`( | )`body | + | ^ + | +help: the opening backtick of an inline code may be missing + | +LL | /// | table`( | `)`body | + | + +help: the closing backtick of an inline code may be missing + | +LL | /// | table`( | )`body` | + | + +help: if you meant to use a literal backtick, escape it + | +LL | /// | table`( | )\`body | + | + + +error: aborting due to 63 previous errors + diff --git a/tests/rustdoc/deref-const-fn.rs b/tests/rustdoc/deref/deref-const-fn.rs similarity index 100% rename from tests/rustdoc/deref-const-fn.rs rename to tests/rustdoc/deref/deref-const-fn.rs diff --git a/tests/rustdoc/deref/deref-multiple-impl-blocks.rs b/tests/rustdoc/deref/deref-multiple-impl-blocks.rs new file mode 100644 index 0000000000000..fa3607c5fc12d --- /dev/null +++ b/tests/rustdoc/deref/deref-multiple-impl-blocks.rs @@ -0,0 +1,43 @@ +#![crate_name="foo"] + +use std::ops::{Deref, DerefMut}; + +// @has foo/struct.Vec.html +// @count - '//h2[@id="deref-methods-Slice"]' 1 +// @count - '//div[@id="deref-methods-Slice-1"]' 1 +// @count - '//div[@id="deref-methods-Slice-1"][@class="impl-items"]' 1 +// @count - '//div[@id="deref-methods-Slice-1"]/div[@class="impl-items"]' 0 +pub struct Vec; + +pub struct Slice; + +impl Deref for Vec { + type Target = Slice; + fn deref(&self) -> &Slice { + &Slice + } +} + +impl DerefMut for Vec { + fn deref_mut(&mut self) -> &mut Slice { + &mut Slice + } +} + +impl Slice { + pub fn sort_floats(&mut self) { + todo!(); + } +} + +impl Slice { + pub fn sort(&mut self) { + todo!(); + } +} + +impl Slice { + pub fn len(&self) { + todo!(); + } +} diff --git a/tests/rustdoc/deref-mut-methods.rs b/tests/rustdoc/deref/deref-mut-methods.rs similarity index 100% rename from tests/rustdoc/deref-mut-methods.rs rename to tests/rustdoc/deref/deref-mut-methods.rs diff --git a/tests/rustdoc/deref-recursive-pathbuf.rs b/tests/rustdoc/deref/deref-recursive-pathbuf.rs similarity index 100% rename from tests/rustdoc/deref-recursive-pathbuf.rs rename to tests/rustdoc/deref/deref-recursive-pathbuf.rs diff --git a/tests/rustdoc/deref-recursive.rs b/tests/rustdoc/deref/deref-recursive.rs similarity index 100% rename from tests/rustdoc/deref-recursive.rs rename to tests/rustdoc/deref/deref-recursive.rs diff --git a/tests/rustdoc/deref-slice-core.rs b/tests/rustdoc/deref/deref-slice-core.rs similarity index 100% rename from tests/rustdoc/deref-slice-core.rs rename to tests/rustdoc/deref/deref-slice-core.rs diff --git a/tests/rustdoc/deref-to-primitive.rs b/tests/rustdoc/deref/deref-to-primitive.rs similarity index 100% rename from tests/rustdoc/deref-to-primitive.rs rename to tests/rustdoc/deref/deref-to-primitive.rs diff --git a/tests/rustdoc/deref-typedef.rs b/tests/rustdoc/deref/deref-typedef.rs similarity index 100% rename from tests/rustdoc/deref-typedef.rs rename to tests/rustdoc/deref/deref-typedef.rs diff --git a/tests/rustdoc/escape-deref-methods.rs b/tests/rustdoc/deref/escape-deref-methods.rs similarity index 100% rename from tests/rustdoc/escape-deref-methods.rs rename to tests/rustdoc/deref/escape-deref-methods.rs diff --git a/tests/rustdoc/issue-100679-sidebar-links-deref.rs b/tests/rustdoc/deref/issue-100679-sidebar-links-deref.rs similarity index 100% rename from tests/rustdoc/issue-100679-sidebar-links-deref.rs rename to tests/rustdoc/deref/issue-100679-sidebar-links-deref.rs diff --git a/tests/rustdoc/recursive-deref-sidebar.rs b/tests/rustdoc/deref/recursive-deref-sidebar.rs similarity index 100% rename from tests/rustdoc/recursive-deref-sidebar.rs rename to tests/rustdoc/deref/recursive-deref-sidebar.rs diff --git a/tests/rustdoc/recursive-deref.rs b/tests/rustdoc/deref/recursive-deref.rs similarity index 100% rename from tests/rustdoc/recursive-deref.rs rename to tests/rustdoc/deref/recursive-deref.rs diff --git a/tests/ui/argument-suggestions/issue-97484.stderr b/tests/ui/argument-suggestions/issue-97484.stderr index a86cbbf1802e1..082564fbc7f88 100644 --- a/tests/ui/argument-suggestions/issue-97484.stderr +++ b/tests/ui/argument-suggestions/issue-97484.stderr @@ -16,7 +16,7 @@ LL | fn foo(a: &A, d: D, e: &E, g: G) {} help: consider borrowing here | LL | foo(&&A, B, C, D, &E, F, G); - | ~~ + | + help: remove the extra arguments | LL - foo(&&A, B, C, D, E, F, G); diff --git a/tests/ui/async-await/issues/issue-102206.stderr b/tests/ui/async-await/issues/issue-102206.stderr index 750b7a886ef9a..cd84505680514 100644 --- a/tests/ui/async-await/issues/issue-102206.stderr +++ b/tests/ui/async-await/issues/issue-102206.stderr @@ -2,14 +2,16 @@ error[E0308]: mismatched types --> $DIR/issue-102206.rs:6:27 | LL | std::mem::size_of_val(foo()); - | --------------------- ^^^^^ - | | | - | | expected `&_`, found future - | | help: consider borrowing here: `&foo()` + | --------------------- ^^^^^ expected `&_`, found future + | | | arguments to this function are incorrect | note: function defined here --> $SRC_DIR/core/src/mem/mod.rs:LL:COL +help: consider borrowing here + | +LL | std::mem::size_of_val(&foo()); + | + error: aborting due to previous error diff --git a/tests/ui/coercion/coercion-slice.stderr b/tests/ui/coercion/coercion-slice.stderr index c7b856a57ebc9..17bbca7a0bdb6 100644 --- a/tests/ui/coercion/coercion-slice.stderr +++ b/tests/ui/coercion/coercion-slice.stderr @@ -2,11 +2,14 @@ error[E0308]: mismatched types --> $DIR/coercion-slice.rs:4:21 | LL | let _: &[i32] = [0]; - | ------ ^^^ - | | | - | | expected `&[i32]`, found `[{integer}; 1]` - | | help: consider borrowing here: `&[0]` + | ------ ^^^ expected `&[i32]`, found `[{integer}; 1]` + | | | expected due to this + | +help: consider borrowing here + | +LL | let _: &[i32] = &[0]; + | + error: aborting due to previous error diff --git a/tests/ui/feature-gates/test-listing-format-json.rs b/tests/ui/feature-gates/test-listing-format-json.rs new file mode 100644 index 0000000000000..2dd0e10b5216f --- /dev/null +++ b/tests/ui/feature-gates/test-listing-format-json.rs @@ -0,0 +1,18 @@ +// no-prefer-dynamic +// compile-flags: --test +// run-flags: --list --format json -Zunstable-options +// run-fail +// check-run-results +// ignore-nightly +// unset-exec-env:RUSTC_BOOTSTRAP + +#![cfg(test)] +#[test] +fn m_test() {} + +#[test] +#[ignore = "not yet implemented"] +fn z_test() {} + +#[test] +fn a_test() {} diff --git a/tests/ui/feature-gates/test-listing-format-json.run.stderr b/tests/ui/feature-gates/test-listing-format-json.run.stderr new file mode 100644 index 0000000000000..e81cb81f32c3f --- /dev/null +++ b/tests/ui/feature-gates/test-listing-format-json.run.stderr @@ -0,0 +1 @@ +error: the option `Z` is only accepted on the nightly compiler diff --git a/tests/ui/inference/deref-suggestion.stderr b/tests/ui/inference/deref-suggestion.stderr index 6f5aacacfc1f1..c58aab4226988 100644 --- a/tests/ui/inference/deref-suggestion.stderr +++ b/tests/ui/inference/deref-suggestion.stderr @@ -98,19 +98,23 @@ error[E0308]: mismatched types --> $DIR/deref-suggestion.rs:40:17 | LL | let s = S { u }; - | ^ - | | - | expected `&u32`, found integer - | help: consider borrowing here: `u: &u` + | ^ expected `&u32`, found integer + | +help: consider borrowing here + | +LL | let s = S { u: &u }; + | ++++ error[E0308]: mismatched types --> $DIR/deref-suggestion.rs:42:20 | LL | let s = S { u: u }; - | ^ - | | - | expected `&u32`, found integer - | help: consider borrowing here: `&u` + | ^ expected `&u32`, found integer + | +help: consider borrowing here + | +LL | let s = S { u: &u }; + | + error[E0308]: mismatched types --> $DIR/deref-suggestion.rs:45:17 diff --git a/tests/ui/issues/issue-11374.stderr b/tests/ui/issues/issue-11374.stderr index 6e1fb1540bb15..879dc5b76c599 100644 --- a/tests/ui/issues/issue-11374.stderr +++ b/tests/ui/issues/issue-11374.stderr @@ -2,10 +2,8 @@ error[E0308]: mismatched types --> $DIR/issue-11374.rs:26:15 | LL | c.read_to(v); - | ------- ^ - | | | - | | expected `&mut [u8]`, found `Vec<_>` - | | help: consider mutably borrowing here: `&mut v` + | ------- ^ expected `&mut [u8]`, found `Vec<_>` + | | | arguments to this method are incorrect | = note: expected mutable reference `&mut [u8]` @@ -15,6 +13,10 @@ note: method defined here | LL | pub fn read_to(&mut self, vec: &mut [u8]) { | ^^^^^^^ -------------- +help: consider mutably borrowing here + | +LL | c.read_to(&mut v); + | ++++ error: aborting due to previous error diff --git a/tests/ui/issues/issue-17033.stderr b/tests/ui/issues/issue-17033.stderr index f26bee5ff45d0..3419c0798595e 100644 --- a/tests/ui/issues/issue-17033.stderr +++ b/tests/ui/issues/issue-17033.stderr @@ -2,11 +2,14 @@ error[E0308]: mismatched types --> $DIR/issue-17033.rs:2:10 | LL | (*p)(()) - | ---- ^^ - | | | - | | expected `&mut ()`, found `()` - | | help: consider mutably borrowing here: `&mut ()` + | ---- ^^ expected `&mut ()`, found `()` + | | | arguments to this function are incorrect + | +help: consider mutably borrowing here + | +LL | (*p)(&mut ()) + | ++++ error: aborting due to previous error diff --git a/tests/ui/issues/issue-18819.stderr b/tests/ui/issues/issue-18819.stderr index 1fc974b609c11..40098f9622fa9 100644 --- a/tests/ui/issues/issue-18819.stderr +++ b/tests/ui/issues/issue-18819.stderr @@ -19,7 +19,7 @@ LL | fn print_x(_: &dyn Foo, extra: &str) { help: consider borrowing here | LL | print_x(&X); - | ~~ + | + help: provide the argument | LL | print_x(/* &dyn Foo */, /* &str */); diff --git a/tests/ui/issues/issue-46302.stderr b/tests/ui/issues/issue-46302.stderr index a6f97c3c9af65..6e126038cc95c 100644 --- a/tests/ui/issues/issue-46302.stderr +++ b/tests/ui/issues/issue-46302.stderr @@ -2,10 +2,12 @@ error[E0308]: mismatched types --> $DIR/issue-46302.rs:3:27 | LL | let u: &str = if true { s[..2] } else { s }; - | ^^^^^^ - | | - | expected `&str`, found `str` - | help: consider borrowing here: `&s[..2]` + | ^^^^^^ expected `&str`, found `str` + | +help: consider borrowing here + | +LL | let u: &str = if true { &s[..2] } else { s }; + | + error: aborting due to previous error diff --git a/tests/ui/issues/issue-46756-consider-borrowing-cast-or-binexpr.stderr b/tests/ui/issues/issue-46756-consider-borrowing-cast-or-binexpr.stderr index e874ded8ec54e..211dd51289595 100644 --- a/tests/ui/issues/issue-46756-consider-borrowing-cast-or-binexpr.stderr +++ b/tests/ui/issues/issue-46756-consider-borrowing-cast-or-binexpr.stderr @@ -2,10 +2,8 @@ error[E0308]: mismatched types --> $DIR/issue-46756-consider-borrowing-cast-or-binexpr.rs:12:42 | LL | light_flows_our_war_of_mocking_words(behold as usize); - | ------------------------------------ ^^^^^^^^^^^^^^^ - | | | - | | expected `&usize`, found `usize` - | | help: consider borrowing here: `&(behold as usize)` + | ------------------------------------ ^^^^^^^^^^^^^^^ expected `&usize`, found `usize` + | | | arguments to this function are incorrect | note: function defined here @@ -13,15 +11,17 @@ note: function defined here | LL | fn light_flows_our_war_of_mocking_words(and_yet: &usize) -> usize { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ --------------- +help: consider borrowing here + | +LL | light_flows_our_war_of_mocking_words(&(behold as usize)); + | ++ + error[E0308]: mismatched types --> $DIR/issue-46756-consider-borrowing-cast-or-binexpr.rs:14:42 | LL | light_flows_our_war_of_mocking_words(with_tears + 4); - | ------------------------------------ ^^^^^^^^^^^^^^ - | | | - | | expected `&usize`, found `usize` - | | help: consider borrowing here: `&(with_tears + 4)` + | ------------------------------------ ^^^^^^^^^^^^^^ expected `&usize`, found `usize` + | | | arguments to this function are incorrect | note: function defined here @@ -29,6 +29,10 @@ note: function defined here | LL | fn light_flows_our_war_of_mocking_words(and_yet: &usize) -> usize { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ --------------- +help: consider borrowing here + | +LL | light_flows_our_war_of_mocking_words(&(with_tears + 4)); + | ++ + error: aborting due to 2 previous errors diff --git a/tests/ui/issues/issue-61106.stderr b/tests/ui/issues/issue-61106.stderr index eff3e6e78495e..aa922e2682d83 100644 --- a/tests/ui/issues/issue-61106.stderr +++ b/tests/ui/issues/issue-61106.stderr @@ -2,10 +2,8 @@ error[E0308]: mismatched types --> $DIR/issue-61106.rs:3:9 | LL | foo(x.clone()); - | --- ^^^^^^^^^ - | | | - | | expected `&str`, found `String` - | | help: consider borrowing here: `&x` + | --- ^^^^^^^^^ expected `&str`, found `String` + | | | arguments to this function are incorrect | note: function defined here @@ -13,6 +11,10 @@ note: function defined here | LL | fn foo(_: &str) {} | ^^^ ------- +help: consider borrowing here + | +LL | foo(&x.clone()); + | + error: aborting due to previous error diff --git a/tests/ui/methods/method-self-arg-1.stderr b/tests/ui/methods/method-self-arg-1.stderr index 9241a8be58f26..dcc21acc5c0f4 100644 --- a/tests/ui/methods/method-self-arg-1.stderr +++ b/tests/ui/methods/method-self-arg-1.stderr @@ -2,10 +2,8 @@ error[E0308]: mismatched types --> $DIR/method-self-arg-1.rs:11:14 | LL | Foo::bar(x); - | -------- ^ - | | | - | | expected `&Foo`, found `Foo` - | | help: consider borrowing here: `&x` + | -------- ^ expected `&Foo`, found `Foo` + | | | arguments to this function are incorrect | note: method defined here @@ -13,6 +11,10 @@ note: method defined here | LL | fn bar(&self) {} | ^^^ ----- +help: consider borrowing here + | +LL | Foo::bar(&x); + | + error[E0308]: mismatched types --> $DIR/method-self-arg-1.rs:13:14 diff --git a/tests/ui/mismatched_types/dont-point-return-on-E0308.stderr b/tests/ui/mismatched_types/dont-point-return-on-E0308.stderr index 13942682d289c..7be94ef4ad663 100644 --- a/tests/ui/mismatched_types/dont-point-return-on-E0308.stderr +++ b/tests/ui/mismatched_types/dont-point-return-on-E0308.stderr @@ -2,10 +2,8 @@ error[E0308]: mismatched types --> $DIR/dont-point-return-on-E0308.rs:11:11 | LL | f(()); - | - ^^ - | | | - | | expected `&()`, found `()` - | | help: consider borrowing here: `&()` + | - ^^ expected `&()`, found `()` + | | | arguments to this function are incorrect | note: function defined here @@ -13,6 +11,10 @@ note: function defined here | LL | async fn f(_: &()) {} | ^ ------ +help: consider borrowing here + | +LL | f(&()); + | + error: aborting due to previous error diff --git a/tests/ui/mut/mut-cross-borrowing.stderr b/tests/ui/mut/mut-cross-borrowing.stderr index 8401827e51f82..8a3076db9b233 100644 --- a/tests/ui/mut/mut-cross-borrowing.stderr +++ b/tests/ui/mut/mut-cross-borrowing.stderr @@ -2,10 +2,8 @@ error[E0308]: mismatched types --> $DIR/mut-cross-borrowing.rs:7:7 | LL | f(x) - | - ^ - | | | - | | expected `&mut isize`, found `Box<{integer}>` - | | help: consider mutably borrowing here: `&mut x` + | - ^ expected `&mut isize`, found `Box<{integer}>` + | | | arguments to this function are incorrect | = note: expected mutable reference `&mut isize` @@ -15,6 +13,10 @@ note: function defined here | LL | fn f(_: &mut isize) {} | ^ ------------- +help: consider mutably borrowing here + | +LL | f(&mut x) + | ++++ error: aborting due to previous error diff --git a/tests/ui/range/issue-54505-no-literals.fixed b/tests/ui/range/issue-54505-no-literals.fixed index 4d8f67182b9ac..71c36c741cc5e 100644 --- a/tests/ui/range/issue-54505-no-literals.fixed +++ b/tests/ui/range/issue-54505-no-literals.fixed @@ -16,60 +16,60 @@ fn main() { take_range(&std::ops::Range { start: 0, end: 1 }); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here - //~| SUGGESTION &std::ops::Range { start: 0, end: 1 } + //~| SUGGESTION & take_range(&::std::ops::Range { start: 0, end: 1 }); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here - //~| SUGGESTION &::std::ops::Range { start: 0, end: 1 } + //~| SUGGESTION & take_range(&std::ops::RangeFrom { start: 1 }); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here - //~| SUGGESTION &std::ops::RangeFrom { start: 1 } + //~| SUGGESTION & take_range(&::std::ops::RangeFrom { start: 1 }); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here - //~| SUGGESTION &::std::ops::RangeFrom { start: 1 } + //~| SUGGESTION & take_range(&std::ops::RangeFull {}); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here - //~| SUGGESTION &std::ops::RangeFull {} + //~| SUGGESTION & take_range(&::std::ops::RangeFull {}); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here - //~| SUGGESTION &::std::ops::RangeFull {} + //~| SUGGESTION & take_range(&std::ops::RangeInclusive::new(0, 1)); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here - //~| SUGGESTION &std::ops::RangeInclusive::new(0, 1) + //~| SUGGESTION & take_range(&::std::ops::RangeInclusive::new(0, 1)); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here - //~| SUGGESTION &::std::ops::RangeInclusive::new(0, 1) + //~| SUGGESTION & take_range(&std::ops::RangeTo { end: 5 }); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here - //~| SUGGESTION &std::ops::RangeTo { end: 5 } + //~| SUGGESTION & take_range(&::std::ops::RangeTo { end: 5 }); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here - //~| SUGGESTION &::std::ops::RangeTo { end: 5 } + //~| SUGGESTION & take_range(&std::ops::RangeToInclusive { end: 5 }); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here - //~| SUGGESTION &std::ops::RangeToInclusive { end: 5 } + //~| SUGGESTION & take_range(&::std::ops::RangeToInclusive { end: 5 }); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here - //~| SUGGESTION &::std::ops::RangeToInclusive { end: 5 } + //~| SUGGESTION & } diff --git a/tests/ui/range/issue-54505-no-literals.rs b/tests/ui/range/issue-54505-no-literals.rs index dc21dcbc2db41..db125d1a22b6d 100644 --- a/tests/ui/range/issue-54505-no-literals.rs +++ b/tests/ui/range/issue-54505-no-literals.rs @@ -16,60 +16,60 @@ fn main() { take_range(std::ops::Range { start: 0, end: 1 }); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here - //~| SUGGESTION &std::ops::Range { start: 0, end: 1 } + //~| SUGGESTION & take_range(::std::ops::Range { start: 0, end: 1 }); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here - //~| SUGGESTION &::std::ops::Range { start: 0, end: 1 } + //~| SUGGESTION & take_range(std::ops::RangeFrom { start: 1 }); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here - //~| SUGGESTION &std::ops::RangeFrom { start: 1 } + //~| SUGGESTION & take_range(::std::ops::RangeFrom { start: 1 }); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here - //~| SUGGESTION &::std::ops::RangeFrom { start: 1 } + //~| SUGGESTION & take_range(std::ops::RangeFull {}); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here - //~| SUGGESTION &std::ops::RangeFull {} + //~| SUGGESTION & take_range(::std::ops::RangeFull {}); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here - //~| SUGGESTION &::std::ops::RangeFull {} + //~| SUGGESTION & take_range(std::ops::RangeInclusive::new(0, 1)); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here - //~| SUGGESTION &std::ops::RangeInclusive::new(0, 1) + //~| SUGGESTION & take_range(::std::ops::RangeInclusive::new(0, 1)); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here - //~| SUGGESTION &::std::ops::RangeInclusive::new(0, 1) + //~| SUGGESTION & take_range(std::ops::RangeTo { end: 5 }); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here - //~| SUGGESTION &std::ops::RangeTo { end: 5 } + //~| SUGGESTION & take_range(::std::ops::RangeTo { end: 5 }); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here - //~| SUGGESTION &::std::ops::RangeTo { end: 5 } + //~| SUGGESTION & take_range(std::ops::RangeToInclusive { end: 5 }); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here - //~| SUGGESTION &std::ops::RangeToInclusive { end: 5 } + //~| SUGGESTION & take_range(::std::ops::RangeToInclusive { end: 5 }); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here - //~| SUGGESTION &::std::ops::RangeToInclusive { end: 5 } + //~| SUGGESTION & } diff --git a/tests/ui/range/issue-54505-no-literals.stderr b/tests/ui/range/issue-54505-no-literals.stderr index d112983848dee..5894bb6ba553f 100644 --- a/tests/ui/range/issue-54505-no-literals.stderr +++ b/tests/ui/range/issue-54505-no-literals.stderr @@ -2,10 +2,8 @@ error[E0308]: mismatched types --> $DIR/issue-54505-no-literals.rs:16:16 | LL | take_range(std::ops::Range { start: 0, end: 1 }); - | ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | | - | | expected `&_`, found `Range<{integer}>` - | | help: consider borrowing here: `&std::ops::Range { start: 0, end: 1 }` + | ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&_`, found `Range<{integer}>` + | | | arguments to this function are incorrect | = note: expected reference `&_` @@ -15,15 +13,17 @@ note: function defined here | LL | fn take_range(_r: &impl RangeBounds) {} | ^^^^^^^^^^ ------------------------- +help: consider borrowing here + | +LL | take_range(&std::ops::Range { start: 0, end: 1 }); + | + error[E0308]: mismatched types --> $DIR/issue-54505-no-literals.rs:21:16 | LL | take_range(::std::ops::Range { start: 0, end: 1 }); - | ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | | - | | expected `&_`, found `Range<{integer}>` - | | help: consider borrowing here: `&::std::ops::Range { start: 0, end: 1 }` + | ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&_`, found `Range<{integer}>` + | | | arguments to this function are incorrect | = note: expected reference `&_` @@ -33,15 +33,17 @@ note: function defined here | LL | fn take_range(_r: &impl RangeBounds) {} | ^^^^^^^^^^ ------------------------- +help: consider borrowing here + | +LL | take_range(&::std::ops::Range { start: 0, end: 1 }); + | + error[E0308]: mismatched types --> $DIR/issue-54505-no-literals.rs:26:16 | LL | take_range(std::ops::RangeFrom { start: 1 }); - | ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | | - | | expected `&_`, found `RangeFrom<{integer}>` - | | help: consider borrowing here: `&std::ops::RangeFrom { start: 1 }` + | ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&_`, found `RangeFrom<{integer}>` + | | | arguments to this function are incorrect | = note: expected reference `&_` @@ -51,15 +53,17 @@ note: function defined here | LL | fn take_range(_r: &impl RangeBounds) {} | ^^^^^^^^^^ ------------------------- +help: consider borrowing here + | +LL | take_range(&std::ops::RangeFrom { start: 1 }); + | + error[E0308]: mismatched types --> $DIR/issue-54505-no-literals.rs:31:16 | LL | take_range(::std::ops::RangeFrom { start: 1 }); - | ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | | - | | expected `&_`, found `RangeFrom<{integer}>` - | | help: consider borrowing here: `&::std::ops::RangeFrom { start: 1 }` + | ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&_`, found `RangeFrom<{integer}>` + | | | arguments to this function are incorrect | = note: expected reference `&_` @@ -69,15 +73,17 @@ note: function defined here | LL | fn take_range(_r: &impl RangeBounds) {} | ^^^^^^^^^^ ------------------------- +help: consider borrowing here + | +LL | take_range(&::std::ops::RangeFrom { start: 1 }); + | + error[E0308]: mismatched types --> $DIR/issue-54505-no-literals.rs:36:16 | LL | take_range(std::ops::RangeFull {}); - | ---------- ^^^^^^^^^^^^^^^^^^^^^^ - | | | - | | expected `&_`, found `RangeFull` - | | help: consider borrowing here: `&std::ops::RangeFull {}` + | ---------- ^^^^^^^^^^^^^^^^^^^^^^ expected `&_`, found `RangeFull` + | | | arguments to this function are incorrect | = note: expected reference `&_` @@ -87,15 +93,17 @@ note: function defined here | LL | fn take_range(_r: &impl RangeBounds) {} | ^^^^^^^^^^ ------------------------- +help: consider borrowing here + | +LL | take_range(&std::ops::RangeFull {}); + | + error[E0308]: mismatched types --> $DIR/issue-54505-no-literals.rs:41:16 | LL | take_range(::std::ops::RangeFull {}); - | ---------- ^^^^^^^^^^^^^^^^^^^^^^^^ - | | | - | | expected `&_`, found `RangeFull` - | | help: consider borrowing here: `&::std::ops::RangeFull {}` + | ---------- ^^^^^^^^^^^^^^^^^^^^^^^^ expected `&_`, found `RangeFull` + | | | arguments to this function are incorrect | = note: expected reference `&_` @@ -105,15 +113,17 @@ note: function defined here | LL | fn take_range(_r: &impl RangeBounds) {} | ^^^^^^^^^^ ------------------------- +help: consider borrowing here + | +LL | take_range(&::std::ops::RangeFull {}); + | + error[E0308]: mismatched types --> $DIR/issue-54505-no-literals.rs:46:16 | LL | take_range(std::ops::RangeInclusive::new(0, 1)); - | ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | | - | | expected `&_`, found `RangeInclusive<{integer}>` - | | help: consider borrowing here: `&std::ops::RangeInclusive::new(0, 1)` + | ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&_`, found `RangeInclusive<{integer}>` + | | | arguments to this function are incorrect | = note: expected reference `&_` @@ -123,15 +133,17 @@ note: function defined here | LL | fn take_range(_r: &impl RangeBounds) {} | ^^^^^^^^^^ ------------------------- +help: consider borrowing here + | +LL | take_range(&std::ops::RangeInclusive::new(0, 1)); + | + error[E0308]: mismatched types --> $DIR/issue-54505-no-literals.rs:51:16 | LL | take_range(::std::ops::RangeInclusive::new(0, 1)); - | ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | | - | | expected `&_`, found `RangeInclusive<{integer}>` - | | help: consider borrowing here: `&::std::ops::RangeInclusive::new(0, 1)` + | ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&_`, found `RangeInclusive<{integer}>` + | | | arguments to this function are incorrect | = note: expected reference `&_` @@ -141,15 +153,17 @@ note: function defined here | LL | fn take_range(_r: &impl RangeBounds) {} | ^^^^^^^^^^ ------------------------- +help: consider borrowing here + | +LL | take_range(&::std::ops::RangeInclusive::new(0, 1)); + | + error[E0308]: mismatched types --> $DIR/issue-54505-no-literals.rs:56:16 | LL | take_range(std::ops::RangeTo { end: 5 }); - | ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | | - | | expected `&_`, found `RangeTo<{integer}>` - | | help: consider borrowing here: `&std::ops::RangeTo { end: 5 }` + | ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&_`, found `RangeTo<{integer}>` + | | | arguments to this function are incorrect | = note: expected reference `&_` @@ -159,15 +173,17 @@ note: function defined here | LL | fn take_range(_r: &impl RangeBounds) {} | ^^^^^^^^^^ ------------------------- +help: consider borrowing here + | +LL | take_range(&std::ops::RangeTo { end: 5 }); + | + error[E0308]: mismatched types --> $DIR/issue-54505-no-literals.rs:61:16 | LL | take_range(::std::ops::RangeTo { end: 5 }); - | ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | | - | | expected `&_`, found `RangeTo<{integer}>` - | | help: consider borrowing here: `&::std::ops::RangeTo { end: 5 }` + | ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&_`, found `RangeTo<{integer}>` + | | | arguments to this function are incorrect | = note: expected reference `&_` @@ -177,15 +193,17 @@ note: function defined here | LL | fn take_range(_r: &impl RangeBounds) {} | ^^^^^^^^^^ ------------------------- +help: consider borrowing here + | +LL | take_range(&::std::ops::RangeTo { end: 5 }); + | + error[E0308]: mismatched types --> $DIR/issue-54505-no-literals.rs:66:16 | LL | take_range(std::ops::RangeToInclusive { end: 5 }); - | ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | | - | | expected `&_`, found `RangeToInclusive<{integer}>` - | | help: consider borrowing here: `&std::ops::RangeToInclusive { end: 5 }` + | ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&_`, found `RangeToInclusive<{integer}>` + | | | arguments to this function are incorrect | = note: expected reference `&_` @@ -195,15 +213,17 @@ note: function defined here | LL | fn take_range(_r: &impl RangeBounds) {} | ^^^^^^^^^^ ------------------------- +help: consider borrowing here + | +LL | take_range(&std::ops::RangeToInclusive { end: 5 }); + | + error[E0308]: mismatched types --> $DIR/issue-54505-no-literals.rs:71:16 | LL | take_range(::std::ops::RangeToInclusive { end: 5 }); - | ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | | - | | expected `&_`, found `RangeToInclusive<{integer}>` - | | help: consider borrowing here: `&::std::ops::RangeToInclusive { end: 5 }` + | ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&_`, found `RangeToInclusive<{integer}>` + | | | arguments to this function are incorrect | = note: expected reference `&_` @@ -213,6 +233,10 @@ note: function defined here | LL | fn take_range(_r: &impl RangeBounds) {} | ^^^^^^^^^^ ------------------------- +help: consider borrowing here + | +LL | take_range(&::std::ops::RangeToInclusive { end: 5 }); + | + error: aborting due to 12 previous errors diff --git a/tests/ui/range/issue-54505-no-std.rs b/tests/ui/range/issue-54505-no-std.rs index 9f378b4836e48..db455fada3bd8 100644 --- a/tests/ui/range/issue-54505-no-std.rs +++ b/tests/ui/range/issue-54505-no-std.rs @@ -29,30 +29,30 @@ fn main() { take_range(0..1); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here - //~| SUGGESTION &(0..1) + //~| SUGGESTION &( take_range(1..); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here - //~| SUGGESTION &(1..) + //~| SUGGESTION &( take_range(..); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here - //~| SUGGESTION &(..) + //~| SUGGESTION &( take_range(0..=1); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here - //~| SUGGESTION &(0..=1) + //~| SUGGESTION &( take_range(..5); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here - //~| SUGGESTION &(..5) + //~| SUGGESTION &( take_range(..=42); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here - //~| SUGGESTION &(..=42) + //~| SUGGESTION &( } diff --git a/tests/ui/range/issue-54505-no-std.stderr b/tests/ui/range/issue-54505-no-std.stderr index a6a9f89da7493..13563d1940cb6 100644 --- a/tests/ui/range/issue-54505-no-std.stderr +++ b/tests/ui/range/issue-54505-no-std.stderr @@ -14,10 +14,8 @@ error[E0308]: mismatched types --> $DIR/issue-54505-no-std.rs:29:16 | LL | take_range(0..1); - | ---------- ^^^^ - | | | - | | expected `&_`, found `Range<{integer}>` - | | help: consider borrowing here: `&(0..1)` + | ---------- ^^^^ expected `&_`, found `Range<{integer}>` + | | | arguments to this function are incorrect | = note: expected reference `&_` @@ -27,15 +25,17 @@ note: function defined here | LL | fn take_range(_r: &impl RangeBounds) {} | ^^^^^^^^^^ ------------------------- +help: consider borrowing here + | +LL | take_range(&(0..1)); + | ++ + error[E0308]: mismatched types --> $DIR/issue-54505-no-std.rs:34:16 | LL | take_range(1..); - | ---------- ^^^ - | | | - | | expected `&_`, found `RangeFrom<{integer}>` - | | help: consider borrowing here: `&(1..)` + | ---------- ^^^ expected `&_`, found `RangeFrom<{integer}>` + | | | arguments to this function are incorrect | = note: expected reference `&_` @@ -45,15 +45,17 @@ note: function defined here | LL | fn take_range(_r: &impl RangeBounds) {} | ^^^^^^^^^^ ------------------------- +help: consider borrowing here + | +LL | take_range(&(1..)); + | ++ + error[E0308]: mismatched types --> $DIR/issue-54505-no-std.rs:39:16 | LL | take_range(..); - | ---------- ^^ - | | | - | | expected `&_`, found `RangeFull` - | | help: consider borrowing here: `&(..)` + | ---------- ^^ expected `&_`, found `RangeFull` + | | | arguments to this function are incorrect | = note: expected reference `&_` @@ -63,15 +65,17 @@ note: function defined here | LL | fn take_range(_r: &impl RangeBounds) {} | ^^^^^^^^^^ ------------------------- +help: consider borrowing here + | +LL | take_range(&(..)); + | ++ + error[E0308]: mismatched types --> $DIR/issue-54505-no-std.rs:44:16 | LL | take_range(0..=1); - | ---------- ^^^^^ - | | | - | | expected `&_`, found `RangeInclusive<{integer}>` - | | help: consider borrowing here: `&(0..=1)` + | ---------- ^^^^^ expected `&_`, found `RangeInclusive<{integer}>` + | | | arguments to this function are incorrect | = note: expected reference `&_` @@ -81,15 +85,17 @@ note: function defined here | LL | fn take_range(_r: &impl RangeBounds) {} | ^^^^^^^^^^ ------------------------- +help: consider borrowing here + | +LL | take_range(&(0..=1)); + | ++ + error[E0308]: mismatched types --> $DIR/issue-54505-no-std.rs:49:16 | LL | take_range(..5); - | ---------- ^^^ - | | | - | | expected `&_`, found `RangeTo<{integer}>` - | | help: consider borrowing here: `&(..5)` + | ---------- ^^^ expected `&_`, found `RangeTo<{integer}>` + | | | arguments to this function are incorrect | = note: expected reference `&_` @@ -99,15 +105,17 @@ note: function defined here | LL | fn take_range(_r: &impl RangeBounds) {} | ^^^^^^^^^^ ------------------------- +help: consider borrowing here + | +LL | take_range(&(..5)); + | ++ + error[E0308]: mismatched types --> $DIR/issue-54505-no-std.rs:54:16 | LL | take_range(..=42); - | ---------- ^^^^^ - | | | - | | expected `&_`, found `RangeToInclusive<{integer}>` - | | help: consider borrowing here: `&(..=42)` + | ---------- ^^^^^ expected `&_`, found `RangeToInclusive<{integer}>` + | | | arguments to this function are incorrect | = note: expected reference `&_` @@ -117,6 +125,10 @@ note: function defined here | LL | fn take_range(_r: &impl RangeBounds) {} | ^^^^^^^^^^ ------------------------- +help: consider borrowing here + | +LL | take_range(&(..=42)); + | ++ + error: aborting due to 8 previous errors diff --git a/tests/ui/range/issue-54505.fixed b/tests/ui/range/issue-54505.fixed index f8298c0b5ceff..9d113ba1d35c2 100644 --- a/tests/ui/range/issue-54505.fixed +++ b/tests/ui/range/issue-54505.fixed @@ -14,30 +14,30 @@ fn main() { take_range(&(0..1)); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here - //~| SUGGESTION &(0..1) + //~| SUGGESTION &( take_range(&(1..)); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here - //~| SUGGESTION &(1..) + //~| SUGGESTION &( take_range(&(..)); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here - //~| SUGGESTION &(..) + //~| SUGGESTION &( take_range(&(0..=1)); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here - //~| SUGGESTION &(0..=1) + //~| SUGGESTION &( take_range(&(..5)); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here - //~| SUGGESTION &(..5) + //~| SUGGESTION &( take_range(&(..=42)); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here - //~| SUGGESTION &(..=42) + //~| SUGGESTION &( } diff --git a/tests/ui/range/issue-54505.rs b/tests/ui/range/issue-54505.rs index 03673252dd3ba..c9929988fe539 100644 --- a/tests/ui/range/issue-54505.rs +++ b/tests/ui/range/issue-54505.rs @@ -14,30 +14,30 @@ fn main() { take_range(0..1); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here - //~| SUGGESTION &(0..1) + //~| SUGGESTION &( take_range(1..); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here - //~| SUGGESTION &(1..) + //~| SUGGESTION &( take_range(..); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here - //~| SUGGESTION &(..) + //~| SUGGESTION &( take_range(0..=1); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here - //~| SUGGESTION &(0..=1) + //~| SUGGESTION &( take_range(..5); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here - //~| SUGGESTION &(..5) + //~| SUGGESTION &( take_range(..=42); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here - //~| SUGGESTION &(..=42) + //~| SUGGESTION &( } diff --git a/tests/ui/range/issue-54505.stderr b/tests/ui/range/issue-54505.stderr index eda047b507a33..0e959fc05e279 100644 --- a/tests/ui/range/issue-54505.stderr +++ b/tests/ui/range/issue-54505.stderr @@ -2,10 +2,8 @@ error[E0308]: mismatched types --> $DIR/issue-54505.rs:14:16 | LL | take_range(0..1); - | ---------- ^^^^ - | | | - | | expected `&_`, found `Range<{integer}>` - | | help: consider borrowing here: `&(0..1)` + | ---------- ^^^^ expected `&_`, found `Range<{integer}>` + | | | arguments to this function are incorrect | = note: expected reference `&_` @@ -15,15 +13,17 @@ note: function defined here | LL | fn take_range(_r: &impl RangeBounds) {} | ^^^^^^^^^^ ------------------------- +help: consider borrowing here + | +LL | take_range(&(0..1)); + | ++ + error[E0308]: mismatched types --> $DIR/issue-54505.rs:19:16 | LL | take_range(1..); - | ---------- ^^^ - | | | - | | expected `&_`, found `RangeFrom<{integer}>` - | | help: consider borrowing here: `&(1..)` + | ---------- ^^^ expected `&_`, found `RangeFrom<{integer}>` + | | | arguments to this function are incorrect | = note: expected reference `&_` @@ -33,15 +33,17 @@ note: function defined here | LL | fn take_range(_r: &impl RangeBounds) {} | ^^^^^^^^^^ ------------------------- +help: consider borrowing here + | +LL | take_range(&(1..)); + | ++ + error[E0308]: mismatched types --> $DIR/issue-54505.rs:24:16 | LL | take_range(..); - | ---------- ^^ - | | | - | | expected `&_`, found `RangeFull` - | | help: consider borrowing here: `&(..)` + | ---------- ^^ expected `&_`, found `RangeFull` + | | | arguments to this function are incorrect | = note: expected reference `&_` @@ -51,15 +53,17 @@ note: function defined here | LL | fn take_range(_r: &impl RangeBounds) {} | ^^^^^^^^^^ ------------------------- +help: consider borrowing here + | +LL | take_range(&(..)); + | ++ + error[E0308]: mismatched types --> $DIR/issue-54505.rs:29:16 | LL | take_range(0..=1); - | ---------- ^^^^^ - | | | - | | expected `&_`, found `RangeInclusive<{integer}>` - | | help: consider borrowing here: `&(0..=1)` + | ---------- ^^^^^ expected `&_`, found `RangeInclusive<{integer}>` + | | | arguments to this function are incorrect | = note: expected reference `&_` @@ -69,15 +73,17 @@ note: function defined here | LL | fn take_range(_r: &impl RangeBounds) {} | ^^^^^^^^^^ ------------------------- +help: consider borrowing here + | +LL | take_range(&(0..=1)); + | ++ + error[E0308]: mismatched types --> $DIR/issue-54505.rs:34:16 | LL | take_range(..5); - | ---------- ^^^ - | | | - | | expected `&_`, found `RangeTo<{integer}>` - | | help: consider borrowing here: `&(..5)` + | ---------- ^^^ expected `&_`, found `RangeTo<{integer}>` + | | | arguments to this function are incorrect | = note: expected reference `&_` @@ -87,15 +93,17 @@ note: function defined here | LL | fn take_range(_r: &impl RangeBounds) {} | ^^^^^^^^^^ ------------------------- +help: consider borrowing here + | +LL | take_range(&(..5)); + | ++ + error[E0308]: mismatched types --> $DIR/issue-54505.rs:39:16 | LL | take_range(..=42); - | ---------- ^^^^^ - | | | - | | expected `&_`, found `RangeToInclusive<{integer}>` - | | help: consider borrowing here: `&(..=42)` + | ---------- ^^^^^ expected `&_`, found `RangeToInclusive<{integer}>` + | | | arguments to this function are incorrect | = note: expected reference `&_` @@ -105,6 +113,10 @@ note: function defined here | LL | fn take_range(_r: &impl RangeBounds) {} | ^^^^^^^^^^ ------------------------- +help: consider borrowing here + | +LL | take_range(&(..=42)); + | ++ + error: aborting due to 6 previous errors diff --git a/tests/ui/range/issue-73553-misinterp-range-literal.stderr b/tests/ui/range/issue-73553-misinterp-range-literal.stderr index 77595b3678ebc..52efa241d0b12 100644 --- a/tests/ui/range/issue-73553-misinterp-range-literal.stderr +++ b/tests/ui/range/issue-73553-misinterp-range-literal.stderr @@ -2,10 +2,8 @@ error[E0308]: mismatched types --> $DIR/issue-73553-misinterp-range-literal.rs:12:10 | LL | demo(tell(1)..tell(10)); - | ---- ^^^^^^^^^^^^^^^^^ - | | | - | | expected `&Range`, found `Range` - | | help: consider borrowing here: `&(tell(1)..tell(10))` + | ---- ^^^^^^^^^^^^^^^^^ expected `&Range`, found `Range` + | | | arguments to this function are incorrect | = note: expected reference `&std::ops::Range` @@ -15,15 +13,17 @@ note: function defined here | LL | fn demo(r: &Range) { | ^^^^ --------- +help: consider borrowing here + | +LL | demo(&(tell(1)..tell(10))); + | ++ + error[E0308]: mismatched types --> $DIR/issue-73553-misinterp-range-literal.rs:14:10 | LL | demo(1..10); - | ---- ^^^^^ - | | | - | | expected `&Range`, found `Range<{integer}>` - | | help: consider borrowing here: `&(1..10)` + | ---- ^^^^^ expected `&Range`, found `Range<{integer}>` + | | | arguments to this function are incorrect | = note: expected reference `&std::ops::Range` @@ -33,6 +33,10 @@ note: function defined here | LL | fn demo(r: &Range) { | ^^^^ --------- +help: consider borrowing here + | +LL | demo(&(1..10)); + | ++ + error: aborting due to 2 previous errors diff --git a/tests/ui/span/coerce-suggestions.stderr b/tests/ui/span/coerce-suggestions.stderr index bb30f000ea7e8..ff840b781f072 100644 --- a/tests/ui/span/coerce-suggestions.stderr +++ b/tests/ui/span/coerce-suggestions.stderr @@ -10,11 +10,14 @@ error[E0308]: mismatched types --> $DIR/coerce-suggestions.rs:9:19 | LL | let x: &str = String::new(); - | ---- ^^^^^^^^^^^^^ - | | | - | | expected `&str`, found `String` - | | help: consider borrowing here: `&String::new()` + | ---- ^^^^^^^^^^^^^ expected `&str`, found `String` + | | | expected due to this + | +help: consider borrowing here + | +LL | let x: &str = &String::new(); + | + error[E0308]: mismatched types --> $DIR/coerce-suggestions.rs:12:10 diff --git a/tests/ui/span/issue-39018.stderr b/tests/ui/span/issue-39018.stderr index bae9363927174..c8c4a5139880d 100644 --- a/tests/ui/span/issue-39018.stderr +++ b/tests/ui/span/issue-39018.stderr @@ -78,10 +78,12 @@ error[E0308]: mismatched types --> $DIR/issue-39018.rs:29:17 | LL | let _ = a + b; - | ^ - | | - | expected `&str`, found `String` - | help: consider borrowing here: `&b` + | ^ expected `&str`, found `String` + | +help: consider borrowing here + | +LL | let _ = a + &b; + | + error[E0369]: cannot add `String` to `&String` --> $DIR/issue-39018.rs:30:15 diff --git a/tests/ui/str/str-array-assignment.stderr b/tests/ui/str/str-array-assignment.stderr index c23400a1d14a7..515cb9e12f858 100644 --- a/tests/ui/str/str-array-assignment.stderr +++ b/tests/ui/str/str-array-assignment.stderr @@ -10,10 +10,12 @@ error[E0308]: mismatched types --> $DIR/str-array-assignment.rs:5:27 | LL | let u: &str = if true { s[..2] } else { s }; - | ^^^^^^ - | | - | expected `&str`, found `str` - | help: consider borrowing here: `&s[..2]` + | ^^^^^^ expected `&str`, found `str` + | +help: consider borrowing here + | +LL | let u: &str = if true { &s[..2] } else { s }; + | + error[E0277]: the size for values of type `str` cannot be known at compilation time --> $DIR/str-array-assignment.rs:7:7 @@ -33,11 +35,14 @@ error[E0308]: mismatched types --> $DIR/str-array-assignment.rs:9:17 | LL | let w: &str = s[..2]; - | ---- ^^^^^^ - | | | - | | expected `&str`, found `str` - | | help: consider borrowing here: `&s[..2]` + | ---- ^^^^^^ expected `&str`, found `str` + | | | expected due to this + | +help: consider borrowing here + | +LL | let w: &str = &s[..2]; + | + error: aborting due to 4 previous errors diff --git a/tests/ui/suggestions/as-ref.stderr b/tests/ui/suggestions/as-ref.stderr index 0ee343ebf9f11..2147d2d92e389 100644 --- a/tests/ui/suggestions/as-ref.stderr +++ b/tests/ui/suggestions/as-ref.stderr @@ -2,61 +2,73 @@ error[E0308]: mismatched types --> $DIR/as-ref.rs:7:29 | LL | opt.map(|arg| takes_ref(arg)); - | --- --------- ^^^ expected `&Foo`, found `Foo` - | | | - | | arguments to this function are incorrect - | help: consider using `as_ref` instead: `as_ref().map` + | --------- ^^^ expected `&Foo`, found `Foo` + | | + | arguments to this function are incorrect | note: function defined here --> $DIR/as-ref.rs:3:4 | LL | fn takes_ref(_: &Foo) {} | ^^^^^^^^^ ------- +help: consider using `as_ref` instead + | +LL | opt.as_ref().map(|arg| takes_ref(arg)); + | +++++++++ error[E0308]: mismatched types --> $DIR/as-ref.rs:8:39 | LL | opt.and_then(|arg| Some(takes_ref(arg))); - | -------- --------- ^^^ expected `&Foo`, found `Foo` - | | | - | | arguments to this function are incorrect - | help: consider using `as_ref` instead: `as_ref().and_then` + | --------- ^^^ expected `&Foo`, found `Foo` + | | + | arguments to this function are incorrect | note: function defined here --> $DIR/as-ref.rs:3:4 | LL | fn takes_ref(_: &Foo) {} | ^^^^^^^^^ ------- +help: consider using `as_ref` instead + | +LL | opt.as_ref().and_then(|arg| Some(takes_ref(arg))); + | +++++++++ error[E0308]: mismatched types --> $DIR/as-ref.rs:10:29 | LL | opt.map(|arg| takes_ref(arg)); - | --- --------- ^^^ expected `&Foo`, found `Foo` - | | | - | | arguments to this function are incorrect - | help: consider using `as_ref` instead: `as_ref().map` + | --------- ^^^ expected `&Foo`, found `Foo` + | | + | arguments to this function are incorrect | note: function defined here --> $DIR/as-ref.rs:3:4 | LL | fn takes_ref(_: &Foo) {} | ^^^^^^^^^ ------- +help: consider using `as_ref` instead + | +LL | opt.as_ref().map(|arg| takes_ref(arg)); + | +++++++++ error[E0308]: mismatched types --> $DIR/as-ref.rs:11:37 | LL | opt.and_then(|arg| Ok(takes_ref(arg))); - | -------- --------- ^^^ expected `&Foo`, found `Foo` - | | | - | | arguments to this function are incorrect - | help: consider using `as_ref` instead: `as_ref().and_then` + | --------- ^^^ expected `&Foo`, found `Foo` + | | + | arguments to this function are incorrect | note: function defined here --> $DIR/as-ref.rs:3:4 | LL | fn takes_ref(_: &Foo) {} | ^^^^^^^^^ ------- +help: consider using `as_ref` instead + | +LL | opt.as_ref().and_then(|arg| Ok(takes_ref(arg))); + | +++++++++ error[E0308]: mismatched types --> $DIR/as-ref.rs:13:29 @@ -101,61 +113,73 @@ error[E0308]: mismatched types --> $DIR/as-ref.rs:22:42 | LL | multiple_ref_opt.map(|arg| takes_ref(arg)); - | --- --------- ^^^ expected `&Foo`, found `Foo` - | | | - | | arguments to this function are incorrect - | help: consider using `as_ref` instead: `as_ref().map` + | --------- ^^^ expected `&Foo`, found `Foo` + | | + | arguments to this function are incorrect | note: function defined here --> $DIR/as-ref.rs:3:4 | LL | fn takes_ref(_: &Foo) {} | ^^^^^^^^^ ------- +help: consider using `as_ref` instead + | +LL | multiple_ref_opt.as_ref().map(|arg| takes_ref(arg)); + | +++++++++ error[E0308]: mismatched types --> $DIR/as-ref.rs:23:52 | LL | multiple_ref_opt.and_then(|arg| Some(takes_ref(arg))); - | -------- --------- ^^^ expected `&Foo`, found `Foo` - | | | - | | arguments to this function are incorrect - | help: consider using `as_ref` instead: `as_ref().and_then` + | --------- ^^^ expected `&Foo`, found `Foo` + | | + | arguments to this function are incorrect | note: function defined here --> $DIR/as-ref.rs:3:4 | LL | fn takes_ref(_: &Foo) {} | ^^^^^^^^^ ------- +help: consider using `as_ref` instead + | +LL | multiple_ref_opt.as_ref().and_then(|arg| Some(takes_ref(arg))); + | +++++++++ error[E0308]: mismatched types --> $DIR/as-ref.rs:25:45 | LL | multiple_ref_result.map(|arg| takes_ref(arg)); - | --- --------- ^^^ expected `&Foo`, found `Foo` - | | | - | | arguments to this function are incorrect - | help: consider using `as_ref` instead: `as_ref().map` + | --------- ^^^ expected `&Foo`, found `Foo` + | | + | arguments to this function are incorrect | note: function defined here --> $DIR/as-ref.rs:3:4 | LL | fn takes_ref(_: &Foo) {} | ^^^^^^^^^ ------- +help: consider using `as_ref` instead + | +LL | multiple_ref_result.as_ref().map(|arg| takes_ref(arg)); + | +++++++++ error[E0308]: mismatched types --> $DIR/as-ref.rs:26:53 | LL | multiple_ref_result.and_then(|arg| Ok(takes_ref(arg))); - | -------- --------- ^^^ expected `&Foo`, found `Foo` - | | | - | | arguments to this function are incorrect - | help: consider using `as_ref` instead: `as_ref().and_then` + | --------- ^^^ expected `&Foo`, found `Foo` + | | + | arguments to this function are incorrect | note: function defined here --> $DIR/as-ref.rs:3:4 | LL | fn takes_ref(_: &Foo) {} | ^^^^^^^^^ ------- +help: consider using `as_ref` instead + | +LL | multiple_ref_result.as_ref().and_then(|arg| Ok(takes_ref(arg))); + | +++++++++ error: aborting due to 11 previous errors diff --git a/tests/ui/suggestions/suggest-ref-macro.rs b/tests/ui/suggestions/suggest-ref-macro.rs index 6f780f32a147b..730f5fa1b5e3d 100644 --- a/tests/ui/suggestions/suggest-ref-macro.rs +++ b/tests/ui/suggestions/suggest-ref-macro.rs @@ -14,7 +14,7 @@ macro_rules! bla { () => { x(123); //~^ ERROR mismatched types - //~| SUGGESTION &mut 123 + //~| SUGGESTION &mut }; ($v:expr) => { x($v) @@ -25,5 +25,5 @@ fn main() { bla!(); bla!(456); //~^ ERROR mismatched types - //~| SUGGESTION &mut 456 + //~| SUGGESTION &mut } diff --git a/tests/ui/suggestions/suggest-ref-macro.stderr b/tests/ui/suggestions/suggest-ref-macro.stderr index 17de49fbd841d..08bc9e86a50f8 100644 --- a/tests/ui/suggestions/suggest-ref-macro.stderr +++ b/tests/ui/suggestions/suggest-ref-macro.stderr @@ -18,10 +18,8 @@ error[E0308]: mismatched types --> $DIR/suggest-ref-macro.rs:15:11 | LL | x(123); - | - ^^^ - | | | - | | expected `&mut i32`, found integer - | | help: consider mutably borrowing here: `&mut 123` + | - ^^^ expected `&mut i32`, found integer + | | | arguments to this function are incorrect ... LL | bla!(); @@ -33,6 +31,10 @@ note: function defined here LL | fn x(_: &mut i32) {} | ^ ----------- = note: this error originates in the macro `bla` (in Nightly builds, run with -Z macro-backtrace for more info) +help: consider mutably borrowing here + | +LL | x(&mut 123); + | ++++ error[E0308]: mismatched types --> $DIR/suggest-ref-macro.rs:26:10 @@ -41,16 +43,17 @@ LL | x($v) | - arguments to this function are incorrect ... LL | bla!(456); - | ^^^ - | | - | expected `&mut i32`, found integer - | help: consider mutably borrowing here: `&mut 456` + | ^^^ expected `&mut i32`, found integer | note: function defined here --> $DIR/suggest-ref-macro.rs:11:4 | LL | fn x(_: &mut i32) {} | ^ ----------- +help: consider mutably borrowing here + | +LL | bla!(&mut 456); + | ++++ error: aborting due to 3 previous errors diff --git a/tests/ui/test-attrs/tests-listing-format-json.rs b/tests/ui/test-attrs/tests-listing-format-json.rs index 18f1521eeeb1c..5afc2746fe4e0 100644 --- a/tests/ui/test-attrs/tests-listing-format-json.rs +++ b/tests/ui/test-attrs/tests-listing-format-json.rs @@ -3,6 +3,7 @@ // run-flags: --list --format json -Zunstable-options // run-pass // check-run-results +// only-nightly // normalize-stdout-test: "fake-test-src-base/test-attrs/" -> "$$DIR/" // normalize-stdout-test: "fake-test-src-base\\test-attrs\\" -> "$$DIR/" diff --git a/tests/ui/test-attrs/tests-listing-format-json.run.stdout b/tests/ui/test-attrs/tests-listing-format-json.run.stdout index b4131e97c34bc..33cc939b59f5d 100644 --- a/tests/ui/test-attrs/tests-listing-format-json.run.stdout +++ b/tests/ui/test-attrs/tests-listing-format-json.run.stdout @@ -1,5 +1,5 @@ { "type": "suite", "event": "discovery" } -{ "type": "test", "event": "discovered", "name": "a_test", "ignore": false, "ignore_message": "", "source_path": "$DIR/tests-listing-format-json.rs", "start_line": 20, "start_col": 4, "end_line": 20, "end_col": 10 } -{ "type": "test", "event": "discovered", "name": "m_test", "ignore": false, "ignore_message": "", "source_path": "$DIR/tests-listing-format-json.rs", "start_line": 13, "start_col": 4, "end_line": 13, "end_col": 10 } -{ "type": "test", "event": "discovered", "name": "z_test", "ignore": true, "ignore_message": "not yet implemented", "source_path": "$DIR/tests-listing-format-json.rs", "start_line": 17, "start_col": 4, "end_line": 17, "end_col": 10 } +{ "type": "test", "event": "discovered", "name": "a_test", "ignore": false, "ignore_message": "", "source_path": "$DIR/tests-listing-format-json.rs", "start_line": 21, "start_col": 4, "end_line": 21, "end_col": 10 } +{ "type": "test", "event": "discovered", "name": "m_test", "ignore": false, "ignore_message": "", "source_path": "$DIR/tests-listing-format-json.rs", "start_line": 14, "start_col": 4, "end_line": 14, "end_col": 10 } +{ "type": "test", "event": "discovered", "name": "z_test", "ignore": true, "ignore_message": "not yet implemented", "source_path": "$DIR/tests-listing-format-json.rs", "start_line": 18, "start_col": 4, "end_line": 18, "end_col": 10 } { "type": "suite", "event": "completed", "tests": 3, "benchmarks": 0, "total": 3, "ignored": 1 } diff --git a/tests/ui/type/type-mismatch.stderr b/tests/ui/type/type-mismatch.stderr index 67a1f893050cd..ce6f29d354fd1 100644 --- a/tests/ui/type/type-mismatch.stderr +++ b/tests/ui/type/type-mismatch.stderr @@ -378,10 +378,8 @@ error[E0308]: mismatched types --> $DIR/type-mismatch.rs:47:23 | LL | want::<&Foo>(f); - | ----------------- ^ - | | | - | | expected `&Foo`, found `Foo` - | | help: consider borrowing here: `&f` + | ----------------- ^ expected `&Foo`, found `Foo` + | | | arguments to this function are incorrect | = note: expected reference `&Foo` @@ -391,6 +389,10 @@ note: function defined here | LL | fn want(t: T) {} | ^^^^ ---- +help: consider borrowing here + | +LL | want::<&Foo>(&f); + | + error[E0308]: mismatched types --> $DIR/type-mismatch.rs:48:26 @@ -556,10 +558,8 @@ error[E0308]: mismatched types --> $DIR/type-mismatch.rs:61:26 | LL | want::<&Foo>(f); - | -------------------- ^ - | | | - | | expected `&Foo`, found `Foo` - | | help: consider borrowing here: `&f` + | -------------------- ^ expected `&Foo`, found `Foo` + | | | arguments to this function are incorrect | = note: expected reference `&Foo` @@ -569,6 +569,10 @@ note: function defined here | LL | fn want(t: T) {} | ^^^^ ---- +help: consider borrowing here + | +LL | want::<&Foo>(&f); + | + error[E0308]: mismatched types --> $DIR/type-mismatch.rs:65:19 diff --git a/tests/ui/typeck/bad-type-in-vec-contains.stderr b/tests/ui/typeck/bad-type-in-vec-contains.stderr index 72533ab1fa37f..b9b3a5fe5ec8f 100644 --- a/tests/ui/typeck/bad-type-in-vec-contains.stderr +++ b/tests/ui/typeck/bad-type-in-vec-contains.stderr @@ -2,16 +2,18 @@ error[E0308]: mismatched types --> $DIR/bad-type-in-vec-contains.rs:5:21 | LL | primes.contains(3); - | -------- ^ - | | | - | | expected `&_`, found integer - | | help: consider borrowing here: `&3` + | -------- ^ expected `&_`, found integer + | | | arguments to this method are incorrect | = note: expected reference `&_` found type `{integer}` note: method defined here --> $SRC_DIR/core/src/slice/mod.rs:LL:COL +help: consider borrowing here + | +LL | primes.contains(&3); + | + error: aborting due to previous error diff --git a/tests/ui/typeck/issue-13853.stderr b/tests/ui/typeck/issue-13853.stderr index 11d34f5b93b0c..8ecb8b680160b 100644 --- a/tests/ui/typeck/issue-13853.stderr +++ b/tests/ui/typeck/issue-13853.stderr @@ -20,10 +20,8 @@ error[E0308]: mismatched types --> $DIR/issue-13853.rs:37:13 | LL | iterate(graph); - | ------- ^^^^^ - | | | - | | expected `&_`, found `Vec` - | | help: consider borrowing here: `&graph` + | ------- ^^^^^ expected `&_`, found `Vec` + | | | arguments to this function are incorrect | = note: expected reference `&_` @@ -33,6 +31,10 @@ note: function defined here | LL | fn iterate>(graph: &G) { | ^^^^^^^ --------- +help: consider borrowing here + | +LL | iterate(&graph); + | + error: aborting due to 3 previous errors diff --git a/tests/ui/unsized-locals/suggest-borrow.stderr b/tests/ui/unsized-locals/suggest-borrow.stderr index d456c16de0dc8..8741b35cdcff8 100644 --- a/tests/ui/unsized-locals/suggest-borrow.stderr +++ b/tests/ui/unsized-locals/suggest-borrow.stderr @@ -16,11 +16,14 @@ error[E0308]: mismatched types --> $DIR/suggest-borrow.rs:3:20 | LL | let x: &[u8] = vec!(1, 2, 3)[..]; - | ----- ^^^^^^^^^^^^^^^^^ - | | | - | | expected `&[u8]`, found `[{integer}]` - | | help: consider borrowing here: `&vec!(1, 2, 3)[..]` + | ----- ^^^^^^^^^^^^^^^^^ expected `&[u8]`, found `[{integer}]` + | | | expected due to this + | +help: consider borrowing here + | +LL | let x: &[u8] = &vec!(1, 2, 3)[..]; + | + error[E0308]: mismatched types --> $DIR/suggest-borrow.rs:4:19