diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index e01e80939cad7..aa213cd072058 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -1655,11 +1655,11 @@ impl HandlerInner { let backtrace = std::env::var_os("RUST_BACKTRACE").map_or(true, |x| &x != "0"); for bug in bugs { if let Some(file) = self.ice_file.as_ref() - && let Ok(mut out) = std::fs::File::options().append(true).open(file) + && let Ok(mut out) = std::fs::File::options().create(true).append(true).open(file) { let _ = write!( &mut out, - "\n\ndelayed span bug: {}\n{}", + "delayed span bug: {}\n{}\n", bug.inner.styled_message().iter().filter_map(|(msg, _)| msg.as_str()).collect::(), &bug.note ); diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs index a475972219966..c68f2d94f3521 100644 --- a/compiler/rustc_hir_typeck/src/callee.rs +++ b/compiler/rustc_hir_typeck/src/callee.rs @@ -531,8 +531,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return; } - let up_to_rcvr_span = segment.ident.span.until(callee_expr.span); - let rest_span = callee_expr.span.shrink_to_hi().to(call_expr.span.shrink_to_hi()); + let Some(callee_expr_span) = callee_expr.span.find_ancestor_inside(call_expr.span) + else { + return; + }; + let up_to_rcvr_span = segment.ident.span.until(callee_expr_span); + let rest_span = callee_expr_span.shrink_to_hi().to(call_expr.span.shrink_to_hi()); let rest_snippet = if let Some(first) = rest.first() { self.tcx .sess diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl index 252177932e437..7692dd3cdd405 100644 --- a/compiler/rustc_lint/messages.ftl +++ b/compiler/rustc_lint/messages.ftl @@ -155,8 +155,6 @@ lint_builtin_unused_doc_comment = unused doc comment lint_builtin_while_true = denote infinite loops with `loop {"{"} ... {"}"}` .suggestion = use `loop` -lint_cast_ref_to_mut = casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell` - lint_check_name_deprecated = lint name `{$lint_name}` is deprecated and does not have an effect anymore. Use: {$new_name} lint_check_name_unknown = unknown lint: `{$lint_name}` @@ -320,6 +318,8 @@ lint_invalid_nan_comparisons_eq_ne = incorrect NaN comparison, NaN cannot be dir lint_invalid_nan_comparisons_lt_le_gt_ge = incorrect NaN comparison, NaN is not orderable +lint_invalid_reference_casting = casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell` + lint_lintpass_by_hand = implementing `LintPass` by hand .help = try using `declare_lint_pass!` or `impl_lint_pass!` instead diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index beb38dbb94c32..53089294fe2e6 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -50,7 +50,6 @@ extern crate tracing; mod array_into_iter; pub mod builtin; -mod cast_ref_to_mut; mod context; mod deref_into_dyn_supertrait; mod drop_forget_useless; @@ -78,6 +77,7 @@ mod opaque_hidden_inferred_bound; mod pass_by_value; mod passes; mod redundant_semicolon; +mod reference_casting; mod traits; mod types; mod unused; @@ -99,7 +99,6 @@ use rustc_span::Span; use array_into_iter::ArrayIntoIter; use builtin::*; -use cast_ref_to_mut::*; use deref_into_dyn_supertrait::*; use drop_forget_useless::*; use enum_intrinsics_non_enums::EnumIntrinsicsNonEnums; @@ -119,6 +118,7 @@ use noop_method_call::*; use opaque_hidden_inferred_bound::*; use pass_by_value::*; use redundant_semicolon::*; +use reference_casting::*; use traits::*; use types::*; use unused::*; @@ -218,7 +218,7 @@ late_lint_methods!( BoxPointers: BoxPointers, PathStatements: PathStatements, LetUnderscore: LetUnderscore, - CastRefToMut: CastRefToMut, + InvalidReferenceCasting: InvalidReferenceCasting, // Depends on referenced function signatures in expressions UnusedResults: UnusedResults, NonUpperCaseGlobals: NonUpperCaseGlobals, diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index 2f2a5a933471a..fa55f6e2c7311 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -743,10 +743,10 @@ pub enum InvalidFromUtf8Diag { }, } -// cast_ref_to_mut.rs +// reference_casting.rs #[derive(LintDiagnostic)] -#[diag(lint_cast_ref_to_mut)] -pub struct CastRefToMutDiag; +#[diag(lint_invalid_reference_casting)] +pub struct InvalidReferenceCastingDiag; // hidden_unicode_codepoints.rs #[derive(LintDiagnostic)] diff --git a/compiler/rustc_lint/src/cast_ref_to_mut.rs b/compiler/rustc_lint/src/reference_casting.rs similarity index 80% rename from compiler/rustc_lint/src/cast_ref_to_mut.rs rename to compiler/rustc_lint/src/reference_casting.rs index 82bb70bc9e781..d343aaf35d5bb 100644 --- a/compiler/rustc_lint/src/cast_ref_to_mut.rs +++ b/compiler/rustc_lint/src/reference_casting.rs @@ -3,15 +3,16 @@ use rustc_hir::{Expr, ExprKind, MutTy, TyKind, UnOp}; use rustc_middle::ty; use rustc_span::sym; -use crate::{lints::CastRefToMutDiag, LateContext, LateLintPass, LintContext}; +use crate::{lints::InvalidReferenceCastingDiag, LateContext, LateLintPass, LintContext}; declare_lint! { - /// The `cast_ref_to_mut` lint checks for casts of `&T` to `&mut T` + /// The `invalid_reference_casting` lint checks for casts of `&T` to `&mut T` /// without using interior mutability. /// /// ### Example /// /// ```rust,compile_fail + /// # #![deny(invalid_reference_casting)] /// fn x(r: &i32) { /// unsafe { /// *(r as *const i32 as *mut i32) += 1; @@ -28,14 +29,14 @@ declare_lint! { /// /// `UnsafeCell` is the only way to obtain aliasable data that is considered /// mutable. - CAST_REF_TO_MUT, - Deny, + INVALID_REFERENCE_CASTING, + Allow, "casts of `&T` to `&mut T` without interior mutability" } -declare_lint_pass!(CastRefToMut => [CAST_REF_TO_MUT]); +declare_lint_pass!(InvalidReferenceCasting => [INVALID_REFERENCE_CASTING]); -impl<'tcx> LateLintPass<'tcx> for CastRefToMut { +impl<'tcx> LateLintPass<'tcx> for InvalidReferenceCasting { fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) { let ExprKind::Unary(UnOp::Deref, e) = &expr.kind else { return; @@ -68,7 +69,7 @@ impl<'tcx> LateLintPass<'tcx> for CastRefToMut { let e = e.peel_blocks(); if let ty::Ref(..) = cx.typeck_results().node_type(e.hir_id).kind() { - cx.emit_spanned_lint(CAST_REF_TO_MUT, expr.span, CastRefToMutDiag); + cx.emit_spanned_lint(INVALID_REFERENCE_CASTING, expr.span, InvalidReferenceCastingDiag); } } } diff --git a/compiler/rustc_mir_transform/src/coverage/spans.rs b/compiler/rustc_mir_transform/src/coverage/spans.rs index 35cf9ea5f91cd..deebf5345bac9 100644 --- a/compiler/rustc_mir_transform/src/coverage/spans.rs +++ b/compiler/rustc_mir_transform/src/coverage/spans.rs @@ -11,7 +11,7 @@ use rustc_middle::ty::TyCtxt; use rustc_span::source_map::original_sp; use rustc_span::{BytePos, ExpnKind, MacroKind, Span, Symbol}; -use std::cell::RefCell; +use std::cell::OnceCell; use std::cmp::Ordering; #[derive(Debug, Copy, Clone)] @@ -67,7 +67,7 @@ impl CoverageStatement { pub(super) struct CoverageSpan { pub span: Span, pub expn_span: Span, - pub current_macro_or_none: RefCell>>, + pub current_macro_or_none: OnceCell>, pub bcb: BasicCoverageBlock, pub coverage_statements: Vec, pub is_closure: bool, @@ -175,8 +175,7 @@ impl CoverageSpan { /// If the span is part of a macro, returns the macro name symbol. pub fn current_macro(&self) -> Option { self.current_macro_or_none - .borrow_mut() - .get_or_insert_with(|| { + .get_or_init(|| { if let ExpnKind::Macro(MacroKind::Bang, current_macro) = self.expn_span.ctxt().outer_expn_data().kind { diff --git a/library/std/src/panicking.rs b/library/std/src/panicking.rs index 0e90d618ad434..15285465c713a 100644 --- a/library/std/src/panicking.rs +++ b/library/std/src/panicking.rs @@ -300,7 +300,7 @@ pub fn panic_hook_with_disk_dump(info: &PanicInfo<'_>, path: Option<&crate::path }; if let Some(path) = path - && let Ok(mut out) = crate::fs::File::options().create(true).write(true).open(&path) + && let Ok(mut out) = crate::fs::File::options().create(true).append(true).open(&path) { write(&mut out, BacktraceStyle::full()); } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index aeae1dd057022..7378422f951f0 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -2818,7 +2818,7 @@ fn clean_use_statement_inner<'tcx>( cx: &mut DocContext<'tcx>, inlined_names: &mut FxHashSet<(ItemType, Symbol)>, ) -> Vec { - if let Res::Def(DefKind::Ctor(..), _) | Res::SelfCtor(..) = path.res { + if should_ignore_res(path.res) { return Vec::new(); } // We need this comparison because some imports (for std types for example) diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index 5c8db3b87744c..baf90b6d73ef6 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -13,7 +13,7 @@ use rustc_ast as ast; use rustc_ast::tokenstream::TokenTree; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; -use rustc_hir::def_id::{DefId, LOCAL_CRATE}; +use rustc_hir::def_id::{DefId, LocalDefId, LOCAL_CRATE}; use rustc_middle::mir; use rustc_middle::mir::interpret::ConstValue; use rustc_middle::ty::{self, GenericArgKind, GenericArgsRef, TyCtxt}; @@ -629,3 +629,35 @@ pub(super) fn display_macro_source( } } } + +pub(crate) fn inherits_doc_hidden( + tcx: TyCtxt<'_>, + mut def_id: LocalDefId, + stop_at: Option, +) -> bool { + let hir = tcx.hir(); + while let Some(id) = tcx.opt_local_parent(def_id) { + if let Some(stop_at) = stop_at && id == stop_at { + return false; + } + def_id = id; + if tcx.is_doc_hidden(def_id.to_def_id()) { + return true; + } else if let Some(node) = hir.find_by_def_id(def_id) && + matches!( + node, + hir::Node::Item(hir::Item { kind: hir::ItemKind::Impl(_), .. }), + ) + { + // `impl` blocks stand a bit on their own: unless they have `#[doc(hidden)]` directly + // on them, they don't inherit it from the parent context. + return false; + } + } + false +} + +#[inline] +pub(crate) fn should_ignore_res(res: Res) -> bool { + matches!(res, Res::Def(DefKind::Ctor(..), _) | Res::SelfCtor(..)) +} diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 2fcf61d004908..89add80433825 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -268,7 +268,7 @@ impl AllTypes { fn append(&mut self, item_name: String, item_type: &ItemType) { let mut url: Vec<_> = item_name.split("::").skip(1).collect(); if let Some(name) = url.pop() { - let new_url = format!("{}/{}.{}.html", url.join("/"), item_type, name); + let new_url = format!("{}/{item_type}.{name}.html", url.join("/")); url.push(name); let name = url.join("::"); match *item_type { @@ -385,16 +385,17 @@ impl AllTypes { fn scrape_examples_help(shared: &SharedContext<'_>) -> String { let mut content = SCRAPE_EXAMPLES_HELP_MD.to_owned(); content.push_str(&format!( - "## More information\n\n\ - If you want more information about this feature, please read the [corresponding chapter in the Rustdoc book]({}/rustdoc/scraped-examples.html).", - DOC_RUST_LANG_ORG_CHANNEL)); + "## More information\n\n\ + If you want more information about this feature, please read the [corresponding chapter in \ + the Rustdoc book]({DOC_RUST_LANG_ORG_CHANNEL}/rustdoc/scraped-examples.html)." + )); let mut ids = IdMap::default(); format!( "
\ -

About scraped examples

\ -
\ -
{}
", +

About scraped examples

\ + \ +
{}
", Markdown { content: &content, links: &[], @@ -517,9 +518,9 @@ fn document_full_inner<'a, 'cx: 'a>( write!( f, "
\ - \ + \ Expand description\ - {}
", + {}", render_markdown(cx, &s, item.links(cx), heading_offset) )?; } else { @@ -701,8 +702,8 @@ fn assoc_href_attr(it: &clean::Item, link: AssocItemLink<'_>, cx: &Context<'_>) let item_type = it.type_(); let href = match link { - AssocItemLink::Anchor(Some(ref id)) => Some(format!("#{}", id)), - AssocItemLink::Anchor(None) => Some(format!("#{}.{}", item_type, name)), + AssocItemLink::Anchor(Some(ref id)) => Some(format!("#{id}")), + AssocItemLink::Anchor(None) => Some(format!("#{item_type}.{name}")), AssocItemLink::GotoSource(did, provided_methods) => { // We're creating a link from the implementation of an associated item to its // declaration in the trait declaration. @@ -722,7 +723,7 @@ fn assoc_href_attr(it: &clean::Item, link: AssocItemLink<'_>, cx: &Context<'_>) }; match href(did.expect_def_id(), cx) { - Ok((url, ..)) => Some(format!("{}#{}.{}", url, item_type, name)), + Ok((url, ..)) => Some(format!("{url}#{item_type}.{name}")), // The link is broken since it points to an external crate that wasn't documented. // Do not create any link in such case. This is better than falling back to a // dummy anchor like `#{item_type}.{name}` representing the `id` of *this* impl item @@ -735,14 +736,14 @@ fn assoc_href_attr(it: &clean::Item, link: AssocItemLink<'_>, cx: &Context<'_>) // In this scenario, the actual `id` of this impl item would be // `#{item_type}.{name}-{n}` for some number `n` (a disambiguator). Err(HrefError::DocumentationNotBuilt) => None, - Err(_) => Some(format!("#{}.{}", item_type, name)), + Err(_) => Some(format!("#{item_type}.{name}")), } } }; // If there is no `href` for the reason explained above, simply do not render it which is valid: // https://html.spec.whatwg.org/multipage/links.html#links-created-by-a-and-area-elements - href.map(|href| format!(" href=\"{}\"", href)).unwrap_or_default() + href.map(|href| format!(" href=\"{href}\"")).unwrap_or_default() } fn assoc_const( @@ -765,7 +766,7 @@ fn assoc_const( ty = ty.print(cx), ); if let Some(default) = default { - write!(w, " = "); + w.write_str(" = "); // FIXME: `.value()` uses `clean::utils::format_integer_with_underscore_sep` under the // hood which adds noisy underscores and a type suffix to number literals. @@ -907,39 +908,41 @@ fn render_stability_since_raw_with_extra( if let Some(ver) = stable_version { stability.push_str(ver.as_str()); - title.push_str(&format!("Stable since Rust version {}", ver)); + title.push_str(&format!("Stable since Rust version {ver}")); } let const_title_and_stability = match const_stability { Some(ConstStability { level: StabilityLevel::Stable { since, .. }, .. }) if Some(since) != containing_const_ver => { - Some((format!("const since {}", since), format!("const: {}", since))) + Some((format!("const since {since}"), format!("const: {since}"))) } Some(ConstStability { level: StabilityLevel::Unstable { issue, .. }, feature, .. }) => { let unstable = if let Some(n) = issue { format!( - r#"unstable"#, - n, feature + r#"unstable"# ) } else { String::from("unstable") }; - Some((String::from("const unstable"), format!("const: {}", unstable))) + Some((String::from("const unstable"), format!("const: {unstable}"))) } _ => None, }; if let Some((const_title, const_stability)) = const_title_and_stability { if !title.is_empty() { - title.push_str(&format!(", {}", const_title)); + title.push_str(&format!(", {const_title}")); } else { title.push_str(&const_title); } if !stability.is_empty() { - stability.push_str(&format!(" ({})", const_stability)); + stability.push_str(&format!(" ({const_stability})")); } else { stability.push_str(&const_stability); } @@ -1085,7 +1088,7 @@ pub(crate) fn render_all_impls( let impls = impls.into_inner(); if !impls.is_empty() { write_impl_section_heading(&mut w, "Trait Implementations", "trait-implementations"); - write!(w, "
{}
", impls).unwrap(); + write!(w, "
{impls}
").unwrap(); } if !synthetic.is_empty() { @@ -1183,10 +1186,13 @@ fn render_assoc_items_inner( ); } if !impls_buf.is_empty() { - write!(w, "{}", tmp_buf.into_inner()).unwrap(); - write!(w, "
").unwrap(); - write!(w, "{}", impls_buf.into_inner()).unwrap(); - w.write_str("
").unwrap(); + write!( + w, + "{}
{}
", + tmp_buf.into_inner(), + impls_buf.into_inner() + ) + .unwrap(); } } @@ -1386,7 +1392,7 @@ fn notable_traits_decl(ty: &clean::Type, cx: &Context<'_>) -> (String, String) { } } if out.is_empty() { - write!(&mut out, "",); + out.write_str(""); } (format!("{:#}", ty.print(cx)), out.into_inner()) @@ -1532,25 +1538,25 @@ fn render_impl( let toggled = !doc_buffer.is_empty(); if toggled { let method_toggle_class = if item_type.is_method() { " method-toggle" } else { "" }; - write!(w, "
", method_toggle_class); + write!(w, "
"); } match &*item.kind { clean::MethodItem(..) | clean::TyMethodItem(_) => { // Only render when the method is not static or we allow static methods if render_method_item { - let id = cx.derive_id(format!("{}.{}", item_type, name)); + let id = cx.derive_id(format!("{item_type}.{name}")); let source_id = trait_ .and_then(|trait_| { trait_.items.iter().find(|item| { item.name.map(|n| n.as_str().eq(name.as_str())).unwrap_or(false) }) }) - .map(|item| format!("{}.{}", item.type_(), name)); - write!(w, "
", id, item_type, in_trait_class,); + .map(|item| format!("{}.{name}", item.type_())); + write!(w, "
"); render_rightside(w, cx, item, containing_item, render_mode); if trait_.is_some() { // Anchors are only used on trait impls. - write!(w, "§", id); + write!(w, "§"); } w.write_str("

"); render_assoc_item( @@ -1561,18 +1567,17 @@ fn render_impl( cx, render_mode, ); - w.write_str("

"); - w.write_str("
"); + w.write_str("
"); } } kind @ (clean::TyAssocConstItem(ty) | clean::AssocConstItem(ty, _)) => { - let source_id = format!("{}.{}", item_type, name); + let source_id = format!("{item_type}.{name}"); let id = cx.derive_id(source_id.clone()); - write!(w, "
", id, item_type, in_trait_class); + write!(w, "
"); render_rightside(w, cx, item, containing_item, render_mode); if trait_.is_some() { // Anchors are only used on trait impls. - write!(w, "§", id); + write!(w, "§"); } w.write_str("

"); assoc_const( @@ -1588,16 +1593,15 @@ fn render_impl( "", cx, ); - w.write_str("

"); - w.write_str("
"); + w.write_str("
"); } clean::TyAssocTypeItem(generics, bounds) => { - let source_id = format!("{}.{}", item_type, name); + let source_id = format!("{item_type}.{name}"); let id = cx.derive_id(source_id.clone()); - write!(w, "
", id, item_type, in_trait_class); + write!(w, "
"); if trait_.is_some() { // Anchors are only used on trait impls. - write!(w, "§", id); + write!(w, "§"); } w.write_str("

"); assoc_type( @@ -1610,16 +1614,15 @@ fn render_impl( 0, cx, ); - w.write_str("

"); - w.write_str("
"); + w.write_str("
"); } clean::AssocTypeItem(tydef, _bounds) => { - let source_id = format!("{}.{}", item_type, name); + let source_id = format!("{item_type}.{name}"); let id = cx.derive_id(source_id.clone()); - write!(w, "
", id, item_type, in_trait_class); + write!(w, "
"); if trait_.is_some() { // Anchors are only used on trait impls. - write!(w, "§", id); + write!(w, "§"); } w.write_str("

"); assoc_type( @@ -1632,8 +1635,7 @@ fn render_impl( 0, cx, ); - w.write_str("

"); - w.write_str("
"); + w.write_str("
"); } clean::StrippedItem(..) => return, _ => panic!("can't make docs for trait item with name {:?}", item.name), @@ -1736,10 +1738,10 @@ fn render_impl( close_tags.insert_str(0, "
"); write!( w, - "
", + "
\ + ", if rendering_params.toggle_open_by_default { " open" } else { "" } ); - write!(w, "") } render_impl_summary( w, @@ -1752,15 +1754,15 @@ fn render_impl( aliases, ); if toggled { - write!(w, "") + w.write_str(""); } if let Some(ref dox) = i.impl_item.opt_doc_value() { if trait_.is_none() && i.inner_impl().items.is_empty() { w.write_str( "
\ -
This impl block contains no items.
\ -
", +
This impl block contains no items.
\ + ", ); } write!( @@ -1819,11 +1821,11 @@ fn render_rightside( const_stable_since, if has_src_ref { "" } else { " rightside" }, ); - if let Some(l) = src_href { + if let Some(link) = src_href { if has_stability { - write!(rightside, " · source", l) + write!(rightside, " · source") } else { - write!(rightside, "source", l) + write!(rightside, "source") } } if has_stability && has_src_ref { @@ -1852,10 +1854,13 @@ pub(crate) fn render_impl_summary( } else { format!(" data-aliases=\"{}\"", aliases.join(",")) }; - write!(w, "
", id, aliases); + write!(w, "
"); render_rightside(w, cx, &i.impl_item, containing_item, RenderMode::Normal); - write!(w, "§", id); - write!(w, "

"); + write!( + w, + "§\ +

" + ); if let Some(use_absolute) = use_absolute { write!(w, "{}", inner_impl.print(use_absolute, cx)); @@ -1880,15 +1885,16 @@ pub(crate) fn render_impl_summary( } else { write!(w, "{}", inner_impl.print(false, cx)); } - write!(w, "

"); + w.write_str(""); let is_trait = inner_impl.trait_.is_some(); if is_trait { if let Some(portability) = portability(&i.impl_item, Some(parent)) { write!( w, - "
{}
", - portability + "\ +
{portability}
\ +
", ); } } @@ -1941,7 +1947,7 @@ pub(crate) fn small_url_encode(s: String) -> String { // consistent with itself when encoding them. st += "+"; } else { - write!(st, "%{:02X}", b).unwrap(); + write!(st, "%{b:02X}").unwrap(); } // Invariant: if the current byte is not at the start of a multi-byte character, // we need to get down here so that when the next turn of the loop comes around, @@ -2256,7 +2262,7 @@ fn render_call_locations(mut w: W, cx: &mut Context<'_>, item: &c format!("lines {}-{}", line_lo + 1, line_hi + 1), ) }; - let url = format!("{}{}#{}", cx.root_path(), call_data.url, anchor); + let url = format!("{}{}#{anchor}", cx.root_path(), call_data.url); (url, title) }; @@ -2266,7 +2272,7 @@ fn render_call_locations(mut w: W, cx: &mut Context<'_>, item: &c Ok(contents) => contents, Err(err) => { let span = item.span(tcx).map_or(rustc_span::DUMMY_SP, |span| span.inner()); - tcx.sess.span_err(span, format!("failed to read file {}: {}", path.display(), err)); + tcx.sess.span_err(span, format!("failed to read file {}: {err}", path.display())); return false; } }; @@ -2325,7 +2331,7 @@ fn render_call_locations(mut w: W, cx: &mut Context<'_>, item: &c .unwrap(); if line_ranges.len() > 1 { - write!(w, r#" "#) + w.write_str(r#" "#) .unwrap(); } @@ -2361,7 +2367,7 @@ fn render_call_locations(mut w: W, cx: &mut Context<'_>, item: &c highlight::DecorationInfo(decoration_info), sources::SourceContext::Embedded { offset: line_min, needs_expansion }, ); - write!(w, "").unwrap(); + w.write_str("").unwrap(); true }; @@ -2428,8 +2434,10 @@ fn render_call_locations(mut w: W, cx: &mut Context<'_>, item: &c // For the remaining examples, generate a
    containing links to the source files. if it.peek().is_some() { - write!(w, r#"").unwrap(); } - write!(w, "
").unwrap(); + w.write_str("
").unwrap(); } - write!(w, "").unwrap(); + w.write_str("").unwrap(); } diff --git a/src/librustdoc/passes/check_doc_test_visibility.rs b/src/librustdoc/passes/check_doc_test_visibility.rs index 011ca9a496142..e333a35e8ad29 100644 --- a/src/librustdoc/passes/check_doc_test_visibility.rs +++ b/src/librustdoc/passes/check_doc_test_visibility.rs @@ -7,11 +7,11 @@ use super::Pass; use crate::clean; +use crate::clean::utils::inherits_doc_hidden; use crate::clean::*; use crate::core::DocContext; use crate::html::markdown::{find_testable_code, ErrorCodes, Ignore, LangString}; use crate::visit::DocVisitor; -use crate::visit_ast::inherits_doc_hidden; use rustc_hir as hir; use rustc_middle::lint::LintLevelSource; use rustc_session::lint; diff --git a/src/librustdoc/passes/strip_hidden.rs b/src/librustdoc/passes/strip_hidden.rs index 7b990cd434882..81a90ed498a3b 100644 --- a/src/librustdoc/passes/strip_hidden.rs +++ b/src/librustdoc/passes/strip_hidden.rs @@ -6,11 +6,11 @@ use rustc_span::symbol::sym; use std::mem; use crate::clean; +use crate::clean::utils::inherits_doc_hidden; use crate::clean::{Item, ItemIdSet}; use crate::core::DocContext; use crate::fold::{strip_item, DocFolder}; use crate::passes::{ImplStripper, Pass}; -use crate::visit_ast::inherits_doc_hidden; pub(crate) const STRIP_HIDDEN: Pass = Pass { name: "strip-hidden", diff --git a/src/librustdoc/passes/stripper.rs b/src/librustdoc/passes/stripper.rs index a6d31534f1d1b..64a4ace5b9f8a 100644 --- a/src/librustdoc/passes/stripper.rs +++ b/src/librustdoc/passes/stripper.rs @@ -3,10 +3,10 @@ use rustc_hir::def_id::DefId; use rustc_middle::ty::{TyCtxt, Visibility}; use std::mem; +use crate::clean::utils::inherits_doc_hidden; use crate::clean::{self, Item, ItemId, ItemIdSet}; use crate::fold::{strip_item, DocFolder}; use crate::formats::cache::Cache; -use crate::visit_ast::inherits_doc_hidden; use crate::visit_lib::RustdocEffectiveVisibilities; pub(crate) struct Stripper<'a, 'tcx> { diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index 2f67e12df9191..3bad9ba4e4a72 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs @@ -16,6 +16,7 @@ use rustc_span::Span; use std::mem; +use crate::clean::utils::{inherits_doc_hidden, should_ignore_res}; use crate::clean::{cfg::Cfg, reexport_chain, AttributesExt, NestedAttributesExt}; use crate::core; @@ -73,33 +74,6 @@ fn def_id_to_path(tcx: TyCtxt<'_>, did: DefId) -> Vec { std::iter::once(crate_name).chain(relative).collect() } -pub(crate) fn inherits_doc_hidden( - tcx: TyCtxt<'_>, - mut def_id: LocalDefId, - stop_at: Option, -) -> bool { - let hir = tcx.hir(); - while let Some(id) = tcx.opt_local_parent(def_id) { - if let Some(stop_at) = stop_at && id == stop_at { - return false; - } - def_id = id; - if tcx.is_doc_hidden(def_id.to_def_id()) { - return true; - } else if let Some(node) = hir.find_by_def_id(def_id) && - matches!( - node, - hir::Node::Item(hir::Item { kind: hir::ItemKind::Impl(_), .. }), - ) - { - // `impl` blocks stand a bit on their own: unless they have `#[doc(hidden)]` directly - // on them, they don't inherit it from the parent context. - return false; - } - } - false -} - pub(crate) struct RustdocVisitor<'a, 'tcx> { cx: &'a mut core::DocContext<'tcx>, view_item_stack: LocalDefIdSet, @@ -466,7 +440,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { for &res in &path.res { // Struct and variant constructors and proc macro stubs always show up alongside // their definitions, we've already processed them so just discard these. - if let Res::Def(DefKind::Ctor(..), _) | Res::SelfCtor(..) = res { + if should_ignore_res(res) { continue; } diff --git a/src/tools/clippy/clippy_lints/src/renamed_lints.rs b/src/tools/clippy/clippy_lints/src/renamed_lints.rs index d24215c229245..e532dd61a829b 100644 --- a/src/tools/clippy/clippy_lints/src/renamed_lints.rs +++ b/src/tools/clippy/clippy_lints/src/renamed_lints.rs @@ -31,7 +31,7 @@ pub static RENAMED_LINTS: &[(&str, &str)] = &[ ("clippy::stutter", "clippy::module_name_repetitions"), ("clippy::to_string_in_display", "clippy::recursive_format_impl"), ("clippy::zero_width_space", "clippy::invisible_characters"), - ("clippy::cast_ref_to_mut", "cast_ref_to_mut"), + ("clippy::cast_ref_to_mut", "invalid_reference_casting"), ("clippy::clone_double_ref", "suspicious_double_ref_op"), ("clippy::cmp_nan", "invalid_nan_comparisons"), ("clippy::drop_bounds", "drop_bounds"), diff --git a/src/tools/clippy/tests/ui/rename.fixed b/src/tools/clippy/tests/ui/rename.fixed index cab02bb93c9ce..03d9ea41a0b1b 100644 --- a/src/tools/clippy/tests/ui/rename.fixed +++ b/src/tools/clippy/tests/ui/rename.fixed @@ -28,9 +28,9 @@ #![allow(clippy::module_name_repetitions)] #![allow(clippy::recursive_format_impl)] #![allow(clippy::invisible_characters)] -#![allow(cast_ref_to_mut)] #![allow(suspicious_double_ref_op)] #![allow(invalid_nan_comparisons)] +#![allow(invalid_reference_casting)] #![allow(drop_bounds)] #![allow(dropping_copy_types)] #![allow(dropping_references)] @@ -79,7 +79,7 @@ #![warn(clippy::module_name_repetitions)] #![warn(clippy::recursive_format_impl)] #![warn(clippy::invisible_characters)] -#![warn(cast_ref_to_mut)] +#![warn(invalid_reference_casting)] #![warn(suspicious_double_ref_op)] #![warn(invalid_nan_comparisons)] #![warn(drop_bounds)] diff --git a/src/tools/clippy/tests/ui/rename.rs b/src/tools/clippy/tests/ui/rename.rs index e5e31452149dd..c028fcb5a3769 100644 --- a/src/tools/clippy/tests/ui/rename.rs +++ b/src/tools/clippy/tests/ui/rename.rs @@ -28,9 +28,9 @@ #![allow(clippy::module_name_repetitions)] #![allow(clippy::recursive_format_impl)] #![allow(clippy::invisible_characters)] -#![allow(cast_ref_to_mut)] #![allow(suspicious_double_ref_op)] #![allow(invalid_nan_comparisons)] +#![allow(invalid_reference_casting)] #![allow(drop_bounds)] #![allow(dropping_copy_types)] #![allow(dropping_references)] diff --git a/src/tools/clippy/tests/ui/rename.stderr b/src/tools/clippy/tests/ui/rename.stderr index 783608a084102..4d8a7fd70f454 100644 --- a/src/tools/clippy/tests/ui/rename.stderr +++ b/src/tools/clippy/tests/ui/rename.stderr @@ -174,11 +174,11 @@ error: lint `clippy::zero_width_space` has been renamed to `clippy::invisible_ch LL | #![warn(clippy::zero_width_space)] | ^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::invisible_characters` -error: lint `clippy::cast_ref_to_mut` has been renamed to `cast_ref_to_mut` +error: lint `clippy::cast_ref_to_mut` has been renamed to `invalid_reference_casting` --> $DIR/rename.rs:82:9 | LL | #![warn(clippy::cast_ref_to_mut)] - | ^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `cast_ref_to_mut` + | ^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `invalid_reference_casting` error: lint `clippy::clone_double_ref` has been renamed to `suspicious_double_ref_op` --> $DIR/rename.rs:83:9 diff --git a/src/tools/miri/tests/fail/both_borrows/shr_frozen_violation1.rs b/src/tools/miri/tests/fail/both_borrows/shr_frozen_violation1.rs index 1edd7748cde11..0c7f4b89711ae 100644 --- a/src/tools/miri/tests/fail/both_borrows/shr_frozen_violation1.rs +++ b/src/tools/miri/tests/fail/both_borrows/shr_frozen_violation1.rs @@ -1,7 +1,7 @@ //@revisions: stack tree //@[tree]compile-flags: -Zmiri-tree-borrows -#![allow(cast_ref_to_mut)] +#![allow(invalid_reference_casting)] fn foo(x: &mut i32) -> i32 { *x = 5; diff --git a/src/tools/miri/tests/fail/modifying_constants.rs b/src/tools/miri/tests/fail/modifying_constants.rs index 40ba31dad8f68..0d1bd7929b5b8 100644 --- a/src/tools/miri/tests/fail/modifying_constants.rs +++ b/src/tools/miri/tests/fail/modifying_constants.rs @@ -1,7 +1,7 @@ // This should fail even without validation/SB //@compile-flags: -Zmiri-disable-validation -Zmiri-disable-stacked-borrows -#![allow(cast_ref_to_mut)] +#![allow(invalid_reference_casting)] fn main() { let x = &1; // the `&1` is promoted to a constant, but it used to be that only the pointer is marked static, not the pointee diff --git a/tests/ui/const-generics/issues/issue-100313.rs b/tests/ui/const-generics/issues/issue-100313.rs index 9a9d4721c8494..4e9d3626aa89c 100644 --- a/tests/ui/const-generics/issues/issue-100313.rs +++ b/tests/ui/const-generics/issues/issue-100313.rs @@ -9,7 +9,6 @@ impl T { unsafe { *(B as *const bool as *mut bool) = false; //~^ ERROR evaluation of constant value failed [E0080] - //~| ERROR casting `&T` to `&mut T` is undefined behavior } } } diff --git a/tests/ui/const-generics/issues/issue-100313.stderr b/tests/ui/const-generics/issues/issue-100313.stderr index ffc34a3a41e24..d4b486376cac8 100644 --- a/tests/ui/const-generics/issues/issue-100313.stderr +++ b/tests/ui/const-generics/issues/issue-100313.stderr @@ -1,11 +1,3 @@ -error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell` - --> $DIR/issue-100313.rs:10:13 - | -LL | *(B as *const bool as *mut bool) = false; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: `#[deny(cast_ref_to_mut)]` on by default - error[E0080]: evaluation of constant value failed --> $DIR/issue-100313.rs:10:13 | @@ -18,11 +10,11 @@ note: inside `T::<&true>::set_false` LL | *(B as *const bool as *mut bool) = false; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: inside `_` - --> $DIR/issue-100313.rs:19:5 + --> $DIR/issue-100313.rs:18:5 | LL | x.set_false(); | ^^^^^^^^^^^^^ -error: aborting due to 2 previous errors +error: aborting due to previous error For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/lint/cast_ref_to_mut.rs b/tests/ui/lint/reference_casting.rs similarity index 98% rename from tests/ui/lint/cast_ref_to_mut.rs rename to tests/ui/lint/reference_casting.rs index 745d707014366..9963820499edd 100644 --- a/tests/ui/lint/cast_ref_to_mut.rs +++ b/tests/ui/lint/reference_casting.rs @@ -1,6 +1,7 @@ // check-fail #![feature(ptr_from_ref)] +#![deny(invalid_reference_casting)] extern "C" { // N.B., mutability can be easily incorrect in FFI calls -- as diff --git a/tests/ui/lint/cast_ref_to_mut.stderr b/tests/ui/lint/reference_casting.stderr similarity index 82% rename from tests/ui/lint/cast_ref_to_mut.stderr rename to tests/ui/lint/reference_casting.stderr index baff00d6c0419..d5b9bbef6439f 100644 --- a/tests/ui/lint/cast_ref_to_mut.stderr +++ b/tests/ui/lint/reference_casting.stderr @@ -1,61 +1,65 @@ error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell` - --> $DIR/cast_ref_to_mut.rs:19:9 + --> $DIR/reference_casting.rs:20:9 | LL | (*(a as *const _ as *mut String)).push_str(" world"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: `#[deny(cast_ref_to_mut)]` on by default +note: the lint level is defined here + --> $DIR/reference_casting.rs:4:9 + | +LL | #![deny(invalid_reference_casting)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell` - --> $DIR/cast_ref_to_mut.rs:21:9 + --> $DIR/reference_casting.rs:22:9 | LL | *(a as *const _ as *mut _) = String::from("Replaced"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell` - --> $DIR/cast_ref_to_mut.rs:23:9 + --> $DIR/reference_casting.rs:24:9 | LL | *(a as *const _ as *mut String) += " world"; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell` - --> $DIR/cast_ref_to_mut.rs:25:25 + --> $DIR/reference_casting.rs:26:25 | LL | let _num = &mut *(num as *const i32 as *mut i32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell` - --> $DIR/cast_ref_to_mut.rs:27:25 + --> $DIR/reference_casting.rs:28:25 | LL | let _num = &mut *(num as *const i32).cast_mut(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell` - --> $DIR/cast_ref_to_mut.rs:29:20 + --> $DIR/reference_casting.rs:30:20 | LL | let _num = *{ num as *const i32 }.cast_mut(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell` - --> $DIR/cast_ref_to_mut.rs:31:9 + --> $DIR/reference_casting.rs:32:9 | LL | *std::ptr::from_ref(num).cast_mut() += 1; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell` - --> $DIR/cast_ref_to_mut.rs:33:9 + --> $DIR/reference_casting.rs:34:9 | LL | *std::ptr::from_ref({ num }).cast_mut() += 1; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell` - --> $DIR/cast_ref_to_mut.rs:35:9 + --> $DIR/reference_casting.rs:36:9 | LL | *{ std::ptr::from_ref(num) }.cast_mut() += 1; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell` - --> $DIR/cast_ref_to_mut.rs:37:9 + --> $DIR/reference_casting.rs:38:9 | LL | *(std::ptr::from_ref({ num }) as *mut i32) += 1; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/methods/suggest-method-on-call-with-macro-rcvr.rs b/tests/ui/methods/suggest-method-on-call-with-macro-rcvr.rs new file mode 100644 index 0000000000000..93b7ddf5e9e09 --- /dev/null +++ b/tests/ui/methods/suggest-method-on-call-with-macro-rcvr.rs @@ -0,0 +1,6 @@ +// issue: 114131 + +fn main() { + let hello = len(vec![]); + //~^ ERROR cannot find function `len` in this scope +} diff --git a/tests/ui/methods/suggest-method-on-call-with-macro-rcvr.stderr b/tests/ui/methods/suggest-method-on-call-with-macro-rcvr.stderr new file mode 100644 index 0000000000000..9694f80ab6d0f --- /dev/null +++ b/tests/ui/methods/suggest-method-on-call-with-macro-rcvr.stderr @@ -0,0 +1,15 @@ +error[E0425]: cannot find function `len` in this scope + --> $DIR/suggest-method-on-call-with-macro-rcvr.rs:4:17 + | +LL | let hello = len(vec![]); + | ^^^ not found in this scope + | +help: use the `.` operator to call the method `len` on `&Vec<_>` + | +LL - let hello = len(vec![]); +LL + let hello = vec![].len(); + | + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0425`.