Skip to content

Rollup of 12 pull requests #144799

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 37 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
870f848
Add support for trait associated items
GuillaumeGomez Jan 20, 2025
ef39e42
Better handling of paths in link to def feature
GuillaumeGomez Jan 26, 2025
9457a32
Update to last rustc_hir Visitor changes
GuillaumeGomez Jan 26, 2025
687ac3f
Fix panic if an item does not have a body
GuillaumeGomez May 4, 2025
45231fa
[rustdoc] Display unsafe attrs with edition 2024 `unsafe()` wrappers.
obi1kenobi Jul 23, 2025
5ae2d42
get rid of some false negatives in rustdoc::broken_intra_doc_links
lolbinarycat Nov 7, 2024
87d7d80
adjust more unit tests to reflect more aggressive intra-doc linting
lolbinarycat Nov 8, 2024
a7da4b8
rustdoc::broken_intra_doc_links: no backticks = use old behavior
lolbinarycat Apr 18, 2025
0413481
rustdoc: update tests to match new lint behavior
lolbinarycat Apr 18, 2025
6a7d488
rustdoc::broken_intra_doc_links: only be lenient with shortcut links
lolbinarycat Apr 19, 2025
bd85df1
move bad-intra-doc test into intra-doc dir
lolbinarycat Apr 19, 2025
a73d7e3
fix up issues with internal compiler docs revealed by stricter lint
lolbinarycat Jul 24, 2025
3352dfc
Skip formatting for some compiler documentation code
joshtriplett Jul 26, 2025
7150880
Improve and regularize comment placement in doc code
joshtriplett Jul 26, 2025
b6c54a9
Avoid placing `// FIXME` comments inside doc code blocks
joshtriplett Jul 26, 2025
56c5b1d
Add parentheses around expression arguments to `..`
joshtriplett Jul 26, 2025
1e2d587
Avoid making the start of a doc code block conditional
joshtriplett Jul 26, 2025
ee0118f
[test][AIX] ignore extern_weak linkage test
daltenty Jul 30, 2025
040f71e
loop match: error on `#[const_continue]` outside `#[loop_match]`
folkertdev Jul 25, 2025
f909918
Add human readable name "Cygwin"
Berrysoft Aug 1, 2025
bd7b8b3
Properly pass path to staged `rustc` to `compiletest` self-tests
jieyouxu Aug 1, 2025
d5ffb06
compiletest: Improve diagnostics for line annotation mismatches 2
petrochenkov Jul 31, 2025
32cf3d4
Cleanup the definition of `group_type`
JonathanBrouwer Aug 1, 2025
21ab47e
Add my previous commit name to .mailmap
scrabsha Aug 1, 2025
4c7c9de
Fix safety comment for new_unchecked in niche_types
nilehmann Aug 1, 2025
8b25064
Rollup merge of #132748 - lolbinarycat:rustdoc-intra-doc-link-warn-mo…
GuillaumeGomez Aug 1, 2025
f157bea
Rollup merge of #135771 - GuillaumeGomez:jump-to-def-perf, r=fmease
GuillaumeGomez Aug 1, 2025
67aa272
Rollup merge of #143360 - folkertdev:const-continue-outside-loop-matc…
GuillaumeGomez Aug 1, 2025
e1e3e15
Rollup merge of #143662 - obi1kenobi:pg/unsafe-attribute-wrappers, r=…
GuillaumeGomez Aug 1, 2025
940b94a
Rollup merge of #144478 - joshtriplett:doc-code-formatting-prep, r=Am…
GuillaumeGomez Aug 1, 2025
5987096
Rollup merge of #144703 - daltenty:daltenty/extern-weak, r=Noratrieb
GuillaumeGomez Aug 1, 2025
adcbd97
Rollup merge of #144747 - petrochenkov:annusexp2, r=RalfJung
GuillaumeGomez Aug 1, 2025
77935d7
Rollup merge of #144766 - Berrysoft:patch-1, r=GuillaumeGomez
GuillaumeGomez Aug 1, 2025
fbcf9dc
Rollup merge of #144782 - jieyouxu:compiletest-selftests, r=Kobzol
GuillaumeGomez Aug 1, 2025
deb7036
Rollup merge of #144786 - JonathanBrouwer:cleanup-group-type, r=jdons…
GuillaumeGomez Aug 1, 2025
9bf1762
Rollup merge of #144796 - scrabsha:push-lsnwwpwpnpxr, r=jdonszelmann
GuillaumeGomez Aug 1, 2025
8df1c5d
Rollup merge of #144797 - nilehmann:safety-comment-niche, r=Noratrieb
GuillaumeGomez Aug 1, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .mailmap
Original file line number Diff line number Diff line change
Expand Up @@ -597,6 +597,7 @@ Sam Radhakrishnan <[email protected]>
Samuel Tardieu <[email protected]>
Santiago Pastorino <[email protected]>
Santiago Pastorino <[email protected]> <[email protected]>
Sasha Pourcelot <[email protected]> Sasha <[email protected]>
Scott McMurray <[email protected]>
Scott McMurray <[email protected]> <[email protected]>
Scott Olson <[email protected]> Scott Olson <[email protected]>
Expand Down
61 changes: 36 additions & 25 deletions compiler/rustc_attr_parsing/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,15 +62,23 @@ use crate::attributes::{AttributeParser as _, Combine, Single, WithoutArgs};
use crate::parser::{ArgParser, MetaItemParser, PathParser};
use crate::session_diagnostics::{AttributeParseError, AttributeParseErrorReason, UnknownMetaItem};

macro_rules! group_type {
($stage: ty) => {
LazyLock<(
BTreeMap<&'static [Symbol], Vec<(AttributeTemplate, Box<dyn for<'sess, 'a> Fn(&mut AcceptContext<'_, 'sess, $stage>, &ArgParser<'a>) + Send + Sync>)>>,
Vec<Box<dyn Send + Sync + Fn(&mut FinalizeContext<'_, '_, $stage>) -> Option<AttributeKind>>>
)>
};
type GroupType<S> = LazyLock<GroupTypeInner<S>>;

struct GroupTypeInner<S: Stage> {
accepters: BTreeMap<&'static [Symbol], Vec<GroupTypeInnerAccept<S>>>,
finalizers: Vec<FinalizeFn<S>>,
}

struct GroupTypeInnerAccept<S: Stage> {
template: AttributeTemplate,
accept_fn: AcceptFn<S>,
}

type AcceptFn<S> =
Box<dyn for<'sess, 'a> Fn(&mut AcceptContext<'_, 'sess, S>, &ArgParser<'a>) + Send + Sync>;
type FinalizeFn<S> =
Box<dyn Send + Sync + Fn(&mut FinalizeContext<'_, '_, S>) -> Option<AttributeKind>>;

macro_rules! attribute_parsers {
(
pub(crate) static $name: ident = [$($names: ty),* $(,)?];
Expand All @@ -93,23 +101,26 @@ macro_rules! attribute_parsers {
}
};
(
@[$ty: ty] pub(crate) static $name: ident = [$($names: ty),* $(,)?];
@[$stage: ty] pub(crate) static $name: ident = [$($names: ty),* $(,)?];
) => {
pub(crate) static $name: group_type!($ty) = LazyLock::new(|| {
let mut accepts = BTreeMap::<_, Vec<(AttributeTemplate, Box<dyn for<'sess, 'a> Fn(&mut AcceptContext<'_, 'sess, $ty>, &ArgParser<'a>) + Send + Sync>)>>::new();
let mut finalizes = Vec::<Box<dyn Send + Sync + Fn(&mut FinalizeContext<'_, '_, $ty>) -> Option<AttributeKind>>>::new();
pub(crate) static $name: GroupType<$stage> = LazyLock::new(|| {
let mut accepts = BTreeMap::<_, Vec<GroupTypeInnerAccept<$stage>>>::new();
let mut finalizes = Vec::<FinalizeFn<$stage>>::new();
$(
{
thread_local! {
static STATE_OBJECT: RefCell<$names> = RefCell::new(<$names>::default());
};

for (path, template, accept_fn) in <$names>::ATTRIBUTES {
accepts.entry(*path).or_default().push((*template, Box::new(|cx, args| {
STATE_OBJECT.with_borrow_mut(|s| {
accept_fn(s, cx, args)
accepts.entry(*path).or_default().push(GroupTypeInnerAccept {
template: *template,
accept_fn: Box::new(|cx, args| {
STATE_OBJECT.with_borrow_mut(|s| {
accept_fn(s, cx, args)
})
})
})));
});
}

finalizes.push(Box::new(|cx| {
Expand All @@ -119,7 +130,7 @@ macro_rules! attribute_parsers {
}
)*

(accepts, finalizes)
GroupTypeInner { accepters:accepts, finalizers:finalizes }
});
};
}
Expand Down Expand Up @@ -215,7 +226,7 @@ pub trait Stage: Sized + 'static + Sealed {
type Id: Copy;
const SHOULD_EMIT_LINTS: bool;

fn parsers() -> &'static group_type!(Self);
fn parsers() -> &'static GroupType<Self>;

fn emit_err<'sess>(
&self,
Expand All @@ -230,7 +241,7 @@ impl Stage for Early {
type Id = NodeId;
const SHOULD_EMIT_LINTS: bool = false;

fn parsers() -> &'static group_type!(Self) {
fn parsers() -> &'static GroupType<Self> {
&early::ATTRIBUTE_PARSERS
}
fn emit_err<'sess>(
Expand All @@ -252,7 +263,7 @@ impl Stage for Late {
type Id = HirId;
const SHOULD_EMIT_LINTS: bool = true;

fn parsers() -> &'static group_type!(Self) {
fn parsers() -> &'static GroupType<Self> {
&late::ATTRIBUTE_PARSERS
}
fn emit_err<'sess>(
Expand Down Expand Up @@ -811,8 +822,8 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
let args = parser.args();
let parts = path.segments().map(|i| i.name).collect::<Vec<_>>();

if let Some(accepts) = S::parsers().0.get(parts.as_slice()) {
for (template, accept) in accepts {
if let Some(accepts) = S::parsers().accepters.get(parts.as_slice()) {
for accept in accepts {
let mut cx: AcceptContext<'_, 'sess, S> = AcceptContext {
shared: SharedContext {
cx: self,
Expand All @@ -821,11 +832,11 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
emit_lint: &mut emit_lint,
},
attr_span: lower_span(attr.span),
template,
template: &accept.template,
attr_path: path.get_attribute_path(),
};

accept(&mut cx, args)
(accept.accept_fn)(&mut cx, args)
}
} else {
// If we're here, we must be compiling a tool attribute... Or someone
Expand Down Expand Up @@ -856,7 +867,7 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
}

let mut parsed_attributes = Vec::new();
for f in &S::parsers().1 {
for f in &S::parsers().finalizers {
if let Some(attr) = f(&mut FinalizeContext {
shared: SharedContext {
cx: self,
Expand All @@ -877,7 +888,7 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {

/// Returns whether there is a parser for an attribute with this name
pub fn is_parsed_attribute(path: &[Symbol]) -> bool {
Late::parsers().0.contains_key(path)
Late::parsers().accepters.contains_key(path)
}

fn lower_attr_args(&self, args: &ast::AttrArgs, lower_span: impl Fn(Span) -> Span) -> AttrArgs {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_borrowck/src/region_infer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -417,7 +417,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
/// minimum values.
///
/// For example:
/// ```
/// ```ignore (illustrative)
/// fn foo<'a, 'b>( /* ... */ ) where 'a: 'b { /* ... */ }
/// ```
/// would initialize two variables like so:
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_hir/src/def.rs
Original file line number Diff line number Diff line change
Expand Up @@ -360,7 +360,7 @@ impl DefKind {
/// For example, everything prefixed with `/* Res */` in this example has
/// an associated `Res`:
///
/// ```
/// ```ignore (illustrative)
/// fn str_to_string(s: & /* Res */ str) -> /* Res */ String {
/// /* Res */ String::from(/* Res */ s)
/// }
Expand Down Expand Up @@ -421,7 +421,7 @@ pub enum Res<Id = hir::HirId> {
/// }
///
/// impl Foo for Bar {
/// fn foo() -> Box<Self> { // SelfTyAlias
/// fn foo() -> Box<Self /* SelfTyAlias */> {
/// let _: Self; // SelfTyAlias
///
/// todo!()
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir/src/hir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3016,7 +3016,7 @@ impl fmt::Display for LoopIdError {
}
}

#[derive(Copy, Clone, Debug, HashStable_Generic)]
#[derive(Copy, Clone, Debug, PartialEq, HashStable_Generic)]
pub struct Destination {
/// This is `Some(_)` iff there is an explicit user-specified 'label
pub label: Option<Label>,
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -425,7 +425,7 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for RemapLateParam<'tcx> {
///
/// trait Foo {
/// fn bar() -> impl Deref<Target = impl Sized>;
/// // ^- RPITIT #1 ^- RPITIT #2
/// // ^- RPITIT #1 ^- RPITIT #2
/// }
///
/// impl Foo for () {
Expand Down
50 changes: 28 additions & 22 deletions compiler/rustc_hir_typeck/src/loops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ use std::collections::BTreeMap;
use std::fmt;

use Context::*;
use rustc_ast::Label;
use rustc_hir as hir;
use rustc_hir::attrs::AttributeKind;
use rustc_hir::def::DefKind;
Expand Down Expand Up @@ -42,8 +41,8 @@ enum Context {
ConstBlock,
/// E.g. `#[loop_match] loop { state = 'label: { /* ... */ } }`.
LoopMatch {
/// The label of the labeled block (not of the loop itself).
labeled_block: Label,
/// The destination pointing to the labeled block (not to the loop itself).
labeled_block: Destination,
},
}

Expand Down Expand Up @@ -186,18 +185,18 @@ impl<'hir> Visitor<'hir> for CheckLoopVisitor<'hir> {
{
self.with_context(UnlabeledBlock(b.span.shrink_to_lo()), |v| v.visit_block(b));
}
hir::ExprKind::Break(break_label, ref opt_expr) => {
hir::ExprKind::Break(break_destination, ref opt_expr) => {
if let Some(e) = opt_expr {
self.visit_expr(e);
}

if self.require_label_in_labeled_block(e.span, &break_label, "break") {
if self.require_label_in_labeled_block(e.span, &break_destination, "break") {
// If we emitted an error about an unlabeled break in a labeled
// block, we don't need any further checking for this break any more
return;
}

let loop_id = match break_label.target_id {
let loop_id = match break_destination.target_id {
Ok(loop_id) => Some(loop_id),
Err(hir::LoopIdError::OutsideLoopScope) => None,
Err(hir::LoopIdError::UnlabeledCfInWhileCondition) => {
Expand All @@ -212,18 +211,25 @@ impl<'hir> Visitor<'hir> for CheckLoopVisitor<'hir> {

// A `#[const_continue]` must break to a block in a `#[loop_match]`.
if find_attr!(self.tcx.hir_attrs(e.hir_id), AttributeKind::ConstContinue(_)) {
if let Some(break_label) = break_label.label {
let is_target_label = |cx: &Context| match cx {
Context::LoopMatch { labeled_block } => {
break_label.ident.name == labeled_block.ident.name
}
_ => false,
};
let Some(label) = break_destination.label else {
let span = e.span;
self.tcx.dcx().emit_fatal(ConstContinueBadLabel { span });
};

if !self.cx_stack.iter().rev().any(is_target_label) {
let span = break_label.ident.span;
self.tcx.dcx().emit_fatal(ConstContinueBadLabel { span });
let is_target_label = |cx: &Context| match cx {
Context::LoopMatch { labeled_block } => {
// NOTE: with macro expansion, the label's span might be different here
// even though it does still refer to the same HIR node. A block
// can't have two labels, so the hir_id is a unique identifier.
assert!(labeled_block.target_id.is_ok()); // see `is_loop_match`.
break_destination.target_id == labeled_block.target_id
}
_ => false,
};

if !self.cx_stack.iter().rev().any(is_target_label) {
let span = label.ident.span;
self.tcx.dcx().emit_fatal(ConstContinueBadLabel { span });
}
}

Expand All @@ -249,7 +255,7 @@ impl<'hir> Visitor<'hir> for CheckLoopVisitor<'hir> {
Some(kind) => {
let suggestion = format!(
"break{}",
break_label
break_destination
.label
.map_or_else(String::new, |l| format!(" {}", l.ident))
);
Expand All @@ -259,7 +265,7 @@ impl<'hir> Visitor<'hir> for CheckLoopVisitor<'hir> {
kind: kind.name(),
suggestion,
loop_label,
break_label: break_label.label,
break_label: break_destination.label,
break_expr_kind: &break_expr.kind,
break_expr_span: break_expr.span,
});
Expand All @@ -268,7 +274,7 @@ impl<'hir> Visitor<'hir> for CheckLoopVisitor<'hir> {
}

let sp_lo = e.span.with_lo(e.span.lo() + BytePos("break".len() as u32));
let label_sp = match break_label.label {
let label_sp = match break_destination.label {
Some(label) => sp_lo.with_hi(label.ident.span.hi()),
None => sp_lo.shrink_to_lo(),
};
Expand Down Expand Up @@ -416,7 +422,7 @@ impl<'hir> CheckLoopVisitor<'hir> {
&self,
e: &'hir hir::Expr<'hir>,
body: &'hir hir::Block<'hir>,
) -> Option<Label> {
) -> Option<Destination> {
if !find_attr!(self.tcx.hir_attrs(e.hir_id), AttributeKind::LoopMatch(_)) {
return None;
}
Expand All @@ -438,8 +444,8 @@ impl<'hir> CheckLoopVisitor<'hir> {

let hir::ExprKind::Assign(_, rhs_expr, _) = loop_body_expr.kind else { return None };

let hir::ExprKind::Block(_, label) = rhs_expr.kind else { return None };
let hir::ExprKind::Block(block, label) = rhs_expr.kind else { return None };

label
Some(Destination { label, target_id: Ok(block.hir_id) })
}
}
4 changes: 1 addition & 3 deletions compiler/rustc_hir_typeck/src/upvar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2391,13 +2391,11 @@ fn migration_suggestion_for_2229(
/// let mut p = Point { x: 10, y: 10 };
///
/// let c = || {
/// p.x += 10;
/// // ^ E1 ^
/// p.x += 10; // E1
/// // ...
/// // More code
/// // ...
/// p.x += 10; // E2
/// // ^ E2 ^
/// };
/// ```
/// `CaptureKind` associated with both `E1` and `E2` will be ByRef(MutBorrow),
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_infer/src/infer/outlives/obligations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
//! fn bar<T>(a: T, b: impl for<'a> Fn(&'a T)) {}
//! fn foo<T>(x: T) {
//! bar(x, |y| { /* ... */})
//! // ^ closure arg
//! // ^ closure arg
//! }
//! ```
//!
Expand Down
12 changes: 8 additions & 4 deletions compiler/rustc_middle/src/hir/map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -533,8 +533,10 @@ impl<'tcx> TyCtxt<'tcx> {
/// ```
/// fn foo(x: usize) -> bool {
/// if x == 1 {
/// true // If `get_fn_id_for_return_block` gets passed the `id` corresponding
/// } else { // to this, it will return `foo`'s `HirId`.
/// // If `get_fn_id_for_return_block` gets passed the `id` corresponding to this, it
/// // will return `foo`'s `HirId`.
/// true
/// } else {
/// false
/// }
/// }
Expand All @@ -543,8 +545,10 @@ impl<'tcx> TyCtxt<'tcx> {
/// ```compile_fail,E0308
/// fn foo(x: usize) -> bool {
/// loop {
/// true // If `get_fn_id_for_return_block` gets passed the `id` corresponding
/// } // to this, it will return `None`.
/// // If `get_fn_id_for_return_block` gets passed the `id` corresponding to this, it
/// // will return `None`.
/// true
/// }
/// false
/// }
/// ```
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_middle/src/mir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1017,7 +1017,8 @@ pub struct LocalDecl<'tcx> {
/// ```
/// fn foo(x: &str) {
/// #[allow(unused_mut)]
/// let mut x: u32 = { // <- one unused mut
/// let mut x: u32 = {
/// //^ one unused mut
/// let mut y: u32 = x.parse().unwrap();
/// y + 2
/// };
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_mir_build/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ mir_build_confused = missing patterns are not covered because `{$variable}` is i
mir_build_const_continue_bad_const = could not determine the target branch for this `#[const_continue]`
.label = this value is too generic
mir_build_const_continue_missing_value = a `#[const_continue]` must break to a label with a value
mir_build_const_continue_missing_label_or_value = a `#[const_continue]` must break to a label with a value
mir_build_const_continue_not_const = could not determine the target branch for this `#[const_continue]`
.help = try extracting the expression into a `const` item
Expand Down
Loading
Loading