Skip to content

Commit 0c68443

Browse files
committed
Auto merge of #153642 - matthiaskrgr:rollup-IHw8KqK, r=matthiaskrgr
Rollup of 4 pull requests Successful merges: - #148562 (In `Option::get_or_insert_with()`, forget the `None` instead of dropping it.) - #153325 (tests/ui/cfg: add annotations for reference rules) - #153621 (Remove `TyCtxt::node_span_lint` method) - #153627 (rustdoc-json: Improve docs for `ItemEnum::item_kind`)
2 parents 3bc6ea5 + b01e56d commit 0c68443

35 files changed

+197
-126
lines changed

compiler/rustc_middle/src/lint.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -298,7 +298,6 @@ fn explain_lint_level_source(
298298
/// If you are looking to implement a lint, look for higher level functions,
299299
/// for example:
300300
/// - [`TyCtxt::emit_node_span_lint`]
301-
/// - [`TyCtxt::node_span_lint`]
302301
/// - [`TyCtxt::node_lint`]
303302
/// - `LintContext::opt_span_lint`
304303
///
@@ -488,7 +487,6 @@ pub fn lint_level(
488487
/// for example:
489488
///
490489
/// - [`TyCtxt::emit_node_span_lint`]
491-
/// - [`TyCtxt::node_span_lint`]
492490
/// - [`TyCtxt::node_lint`]
493491
/// - `LintContext::opt_span_lint`
494492
///

compiler/rustc_middle/src/ty/context.rs

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2542,21 +2542,6 @@ impl<'tcx> TyCtxt<'tcx> {
25422542
diag_lint_level(self.sess, lint, level, Some(span.into()), decorator)
25432543
}
25442544

2545-
/// Emit a lint at the appropriate level for a hir node, with an associated span.
2546-
///
2547-
/// [`lint_level`]: rustc_middle::lint::lint_level#decorate-signature
2548-
#[track_caller]
2549-
pub fn node_span_lint(
2550-
self,
2551-
lint: &'static Lint,
2552-
hir_id: HirId,
2553-
span: impl Into<MultiSpan>,
2554-
decorate: impl for<'a, 'b> FnOnce(&'b mut Diag<'a, ()>),
2555-
) {
2556-
let level = self.lint_level_at_node(lint, hir_id);
2557-
lint_level(self.sess, lint, level, Some(span.into()), decorate);
2558-
}
2559-
25602545
/// Find the appropriate span where `use` and outer attributes can be inserted at.
25612546
pub fn crate_level_attribute_injection_span(self) -> Span {
25622547
let node = self.hir_node(hir::CRATE_HIR_ID);

library/core/src/option.rs

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1777,7 +1777,7 @@ impl<T> Option<T> {
17771777
#[rustc_const_unstable(feature = "const_option_ops", issue = "143956")]
17781778
pub const fn get_or_insert_default(&mut self) -> &mut T
17791779
where
1780-
T: [const] Default + [const] Destruct,
1780+
T: [const] Default,
17811781
{
17821782
self.get_or_insert_with(T::default)
17831783
}
@@ -1805,10 +1805,25 @@ impl<T> Option<T> {
18051805
pub const fn get_or_insert_with<F>(&mut self, f: F) -> &mut T
18061806
where
18071807
F: [const] FnOnce() -> T + [const] Destruct,
1808-
T: [const] Destruct,
18091808
{
18101809
if let None = self {
1811-
*self = Some(f());
1810+
// The effect of the following statement is identical to
1811+
// *self = Some(f());
1812+
// except that it does not drop the old value of `*self`. This is not a leak, because
1813+
// we just checked that the old value is `None`, which contains no fields to drop.
1814+
// This implementation strategy
1815+
//
1816+
// * avoids needing a `T: [const] Destruct` bound, to the benefit of `const` callers,
1817+
// * and avoids possibly compiling needless drop code (as would sometimes happen in the
1818+
// previous implementation), to the benefit of non-`const` callers.
1819+
//
1820+
// FIXME(const-hack): It would be nice if this weird trick were made obsolete
1821+
// (though that is likely to be hard/wontfix).
1822+
//
1823+
// It could also be expressed as `unsafe { core::ptr::write(self, Some(f())) }`, but
1824+
// no reason is currently known to use additional unsafe code here.
1825+
1826+
mem::forget(mem::replace(self, Some(f())));
18121827
}
18131828

18141829
// SAFETY: a `None` variant for `self` would have been replaced by a `Some`

library/coretests/tests/option.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -495,6 +495,30 @@ const fn option_const_mut() {
495495
*/
496496
}
497497

498+
/// Test that `Option::get_or_insert_default` is usable in const contexts, including with types that
499+
/// do not satisfy `T: const Destruct`.
500+
#[test]
501+
fn const_get_or_insert_default() {
502+
const OPT_DEFAULT: Option<Vec<bool>> = {
503+
let mut x = None;
504+
x.get_or_insert_default();
505+
x
506+
};
507+
assert!(OPT_DEFAULT.is_some());
508+
}
509+
510+
/// Test that `Option::get_or_insert_with` is usable in const contexts, including with types that
511+
/// do not satisfy `T: const Destruct`.
512+
#[test]
513+
fn const_get_or_insert_with() {
514+
const OPT_WITH: Option<Vec<bool>> = {
515+
let mut x = None;
516+
x.get_or_insert_with(Vec::new);
517+
x
518+
};
519+
assert!(OPT_WITH.is_some());
520+
}
521+
498522
#[test]
499523
fn test_unwrap_drop() {
500524
struct Dtor<'a> {

src/librustdoc/passes/lint/bare_urls.rs

Lines changed: 29 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use std::mem;
66
use std::sync::LazyLock;
77

88
use regex::Regex;
9-
use rustc_errors::Applicability;
9+
use rustc_errors::{Applicability, DiagDecorator};
1010
use rustc_hir::HirId;
1111
use rustc_resolve::rustdoc::pulldown_cmark::{Event, Parser, Tag};
1212
use rustc_resolve::rustdoc::source_span_for_markdown_range;
@@ -24,30 +24,35 @@ pub(super) fn visit_item(cx: &DocContext<'_>, item: &Item, hir_id: HirId, dox: &
2424
let maybe_sp = source_span_for_markdown_range(cx.tcx, dox, &range, &item.attrs.doc_strings)
2525
.map(|(sp, _)| sp);
2626
let sp = maybe_sp.unwrap_or_else(|| item.attr_span(cx.tcx));
27-
cx.tcx.node_span_lint(crate::lint::BARE_URLS, hir_id, sp, |lint| {
28-
lint.primary_message(msg)
29-
.note("bare URLs are not automatically turned into clickable links");
30-
// The fallback of using the attribute span is suitable for
31-
// highlighting where the error is, but not for placing the < and >
32-
if let Some(sp) = maybe_sp {
33-
if let Some(without_brackets) = without_brackets {
34-
lint.multipart_suggestion(
35-
"use an automatic link instead",
36-
vec![(sp, format!("<{without_brackets}>"))],
37-
Applicability::MachineApplicable,
38-
);
39-
} else {
40-
lint.multipart_suggestion(
41-
"use an automatic link instead",
42-
vec![
43-
(sp.shrink_to_lo(), "<".to_string()),
44-
(sp.shrink_to_hi(), ">".to_string()),
45-
],
46-
Applicability::MachineApplicable,
47-
);
27+
cx.tcx.emit_node_span_lint(
28+
crate::lint::BARE_URLS,
29+
hir_id,
30+
sp,
31+
DiagDecorator(|lint| {
32+
lint.primary_message(msg)
33+
.note("bare URLs are not automatically turned into clickable links");
34+
// The fallback of using the attribute span is suitable for
35+
// highlighting where the error is, but not for placing the < and >
36+
if let Some(sp) = maybe_sp {
37+
if let Some(without_brackets) = without_brackets {
38+
lint.multipart_suggestion(
39+
"use an automatic link instead",
40+
vec![(sp, format!("<{without_brackets}>"))],
41+
Applicability::MachineApplicable,
42+
);
43+
} else {
44+
lint.multipart_suggestion(
45+
"use an automatic link instead",
46+
vec![
47+
(sp.shrink_to_lo(), "<".to_string()),
48+
(sp.shrink_to_hi(), ">".to_string()),
49+
],
50+
Applicability::MachineApplicable,
51+
);
52+
}
4853
}
49-
}
50-
});
54+
}),
55+
);
5156
};
5257

5358
let mut p = Parser::new_ext(dox, main_body_opts()).into_offset_iter();

src/rustdoc-json-types/lib.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -683,7 +683,13 @@ pub enum ItemEnum {
683683
}
684684

685685
impl ItemEnum {
686-
/// Returns the [`ItemKind`] of this item.
686+
/// Get just the kind of this item, but with no further data.
687+
///
688+
/// ```rust
689+
/// # use rustdoc_json_types::{ItemKind, ItemEnum};
690+
/// let item = ItemEnum::ExternCrate { name: "libc".to_owned(), rename: None };
691+
/// assert_eq!(item.item_kind(), ItemKind::ExternCrate);
692+
/// ```
687693
pub fn item_kind(&self) -> ItemKind {
688694
match self {
689695
ItemEnum::Module(_) => ItemKind::Module,

src/tools/clippy/clippy.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,5 @@ path = "rustc_lint::context::LintContext::span_lint"
1313
reason = "this function does not add a link to our documentation; please use the `clippy_utils::diagnostics::span_lint*` functions instead"
1414

1515
[[disallowed-methods]]
16-
path = "rustc_middle::ty::context::TyCtxt::node_span_lint"
16+
path = "rustc_middle::ty::context::TyCtxt::emit_node_span_lint"
1717
reason = "this function does not add a link to our documentation; please use the `clippy_utils::diagnostics::span_lint_hir*` functions instead"

src/tools/clippy/clippy_utils/src/diagnostics.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -326,14 +326,14 @@ pub fn span_lint_hir_and_then(
326326
f: impl FnOnce(&mut Diag<'_, ()>),
327327
) {
328328
#[expect(clippy::disallowed_methods)]
329-
cx.tcx.node_span_lint(lint, hir_id, sp, |diag| {
329+
cx.tcx.emit_node_span_lint(lint, hir_id, sp, rustc_errors::DiagDecorator(|diag| {
330330
diag.primary_message(msg);
331331
f(diag);
332332
docs_link(diag, lint);
333333

334334
#[cfg(debug_assertions)]
335335
validate_diag(diag);
336-
});
336+
}));
337337
}
338338

339339
/// Add a span lint with a suggestion on how to fix it.

src/tools/clippy/tests/ui-internal/disallow_span_lint.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ extern crate rustc_hir;
66
extern crate rustc_lint;
77
extern crate rustc_middle;
88

9-
use rustc_errors::{DiagMessage, MultiSpan};
9+
use rustc_errors::{DiagDecorator, DiagMessage, MultiSpan};
1010
use rustc_hir::hir_id::HirId;
1111
use rustc_lint::{Lint, LintContext};
1212
use rustc_middle::ty::TyCtxt;
@@ -19,10 +19,10 @@ pub fn a(cx: impl LintContext, lint: &'static Lint, span: impl Into<MultiSpan>,
1919
}
2020

2121
pub fn b(tcx: TyCtxt<'_>, lint: &'static Lint, hir_id: HirId, span: impl Into<MultiSpan>, msg: impl Into<DiagMessage>) {
22-
tcx.node_span_lint(lint, hir_id, span, |lint| {
22+
tcx.emit_node_span_lint(lint, hir_id, span, DiagDecorator(|lint| {
2323
//~^ disallowed_methods
2424
lint.primary_message(msg);
25-
});
25+
}));
2626
}
2727

2828
fn main() {}

tests/ui/cfg/both-true-false.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
/// Test that placing a `cfg(true)` and `cfg(false)` on the same item result in
22
//. it being disabled.`
3+
//@ reference: cfg.attr.duplicates
34

45
#[cfg(false)]
56
#[cfg(true)]

0 commit comments

Comments
 (0)