Skip to content

Rollup of 9 pull requests #145394

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 35 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
f6bdffd
Add Ref/RefMut try_map method
GrigorenkoPV Nov 19, 2023
9c0cfd2
Fix description of unsigned `checked_exact_div`
tautschnig Aug 5, 2025
bc14ad3
strip prefix of temporary file names when it exceeds filesystem name …
tardyp Aug 6, 2025
38df158
cfg_select: Support unbraced expressions
joshtriplett Aug 10, 2025
ebcbcc8
bootstrap: Fix jemalloc 64K page support for aarch64 tools
CathalMullan Aug 13, 2025
ab3717b
rough solution
karolzwolak Apr 28, 2025
9e387a1
simplify the note message
karolzwolak Apr 28, 2025
8bd3a48
bless the tests
karolzwolak Apr 28, 2025
c036255
manually fix rest of the tests
karolzwolak Apr 29, 2025
4e96b2a
add test
karolzwolak Apr 29, 2025
c812af9
don't show the group name for external lints
karolzwolak May 7, 2025
f229895
bless clippy tests
karolzwolak May 7, 2025
d72a98f
add comments and LintGroup struct for more clarity
karolzwolak May 7, 2025
bdff809
fix typo in test
karolzwolak May 9, 2025
002ac81
link rustc_lint module in a comment
karolzwolak May 9, 2025
f39cd04
closure instead of nested fn, remove allow_external arg, and use .find()
karolzwolak May 30, 2025
fe5cec7
add additional example in the error to showcase the behavior
karolzwolak May 30, 2025
4a381ff
rename LintStoreMarker trait to DynLintStore
karolzwolak Jun 1, 2025
c054b48
Revert "link rustc_lint module in a comment"
karolzwolak Jun 1, 2025
d10a8a3
bootstrap: Support passing `--timings` to cargo
joshtriplett Aug 14, 2025
3ecea53
bootstrap: Update completions for new --timings argument
joshtriplett Aug 14, 2025
0241292
take attr style into account in diagnostics
jdonszelmann Aug 11, 2025
18fd6ea
Revert "Correctly handle when there are no unstable items in the docu…
GuillaumeGomez Aug 14, 2025
1975b06
Revert "rustdoc search: add performance note about searchIndexUnstabl…
GuillaumeGomez Aug 14, 2025
2820fcc
Revert "rustdoc: IndexItem::{stability -> is_unstable}"
GuillaumeGomez Aug 14, 2025
a195cf6
Revert "rustdoc search: prefer stable items in search results"
GuillaumeGomez Aug 14, 2025
ad2d090
Rollup merge of #118087 - GrigorenkoPV:refcell_try_map, r=Mark-Simula…
GuillaumeGomez Aug 14, 2025
f22892b
Rollup merge of #140794 - karolzwolak:allow-unused-doc-65464, r=david…
GuillaumeGomez Aug 14, 2025
bfadbe4
Rollup merge of #144947 - tautschnig:remove-stray-checked_div-comment…
GuillaumeGomez Aug 14, 2025
211dd93
Rollup merge of #145005 - tardyp:lto_big_filesize, r=bjorn3
GuillaumeGomez Aug 14, 2025
3c309b0
Rollup merge of #145233 - joshtriplett:cfg-select-expr, r=jieyouxu
GuillaumeGomez Aug 14, 2025
adedc2b
Rollup merge of #145243 - jdonszelmann:inner-attr-errors, r=petrochenkov
GuillaumeGomez Aug 14, 2025
09662f2
Rollup merge of #145353 - CathalMullan:jemalloc-tools, r=Kobzol
GuillaumeGomez Aug 14, 2025
f95a0e4
Rollup merge of #145379 - joshtriplett:bootstrap-timings, r=jieyouxu
GuillaumeGomez Aug 14, 2025
d105953
Rollup merge of #145389 - GuillaumeGomez:unstable-search, r=fmease
GuillaumeGomez Aug 14, 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
4 changes: 2 additions & 2 deletions compiler/rustc_attr_parsing/src/attributes/inline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ impl<S: Stage> SingleAttributeParser<S> for InlineParser {
}
}
ArgParser::NameValue(_) => {
let suggestions =
<Self as SingleAttributeParser<S>>::TEMPLATE.suggestions(false, "inline");
let suggestions = <Self as SingleAttributeParser<S>>::TEMPLATE
.suggestions(cx.attr_style, "inline");
let span = cx.attr_span;
cx.emit_lint(AttributeLintKind::IllFormedAttributeInput { suggestions }, span);
return None;
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_attr_parsing/src/attributes/macro_attrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ impl<S: Stage> AttributeParser<S> for MacroUseParser {
}
}
ArgParser::NameValue(_) => {
let suggestions = MACRO_USE_TEMPLATE.suggestions(false, sym::macro_use);
let suggestions = MACRO_USE_TEMPLATE.suggestions(cx.attr_style, sym::macro_use);
cx.emit_err(session_diagnostics::IllFormedAttributeInputLint {
num_suggestions: suggestions.len(),
suggestions: DiagArgValue::StrListSepByAnd(
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_attr_parsing/src/attributes/must_use.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ impl<S: Stage> SingleAttributeParser<S> for MustUseParser {
Some(value_str)
}
ArgParser::List(_) => {
let suggestions =
<Self as SingleAttributeParser<S>>::TEMPLATE.suggestions(false, "must_use");
let suggestions = <Self as SingleAttributeParser<S>>::TEMPLATE
.suggestions(cx.attr_style, "must_use");
cx.emit_err(session_diagnostics::IllFormedAttributeInputLint {
num_suggestions: suggestions.len(),
suggestions: DiagArgValue::StrListSepByAnd(
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_attr_parsing/src/attributes/test_attrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ impl<S: Stage> SingleAttributeParser<S> for IgnoreParser {
ArgParser::NameValue(name_value) => {
let Some(str_value) = name_value.value_as_str() else {
let suggestions = <Self as SingleAttributeParser<S>>::TEMPLATE
.suggestions(false, "ignore");
.suggestions(cx.attr_style, "ignore");
let span = cx.attr_span;
cx.emit_lint(
AttributeLintKind::IllFormedAttributeInput { suggestions },
Expand All @@ -37,8 +37,8 @@ impl<S: Stage> SingleAttributeParser<S> for IgnoreParser {
Some(str_value)
}
ArgParser::List(_) => {
let suggestions =
<Self as SingleAttributeParser<S>>::TEMPLATE.suggestions(false, "ignore");
let suggestions = <Self as SingleAttributeParser<S>>::TEMPLATE
.suggestions(cx.attr_style, "ignore");
let span = cx.attr_span;
cx.emit_lint(AttributeLintKind::IllFormedAttributeInput { suggestions }, span);
return None;
Expand Down
18 changes: 17 additions & 1 deletion compiler/rustc_attr_parsing/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use std::ops::{Deref, DerefMut};
use std::sync::LazyLock;

use private::Sealed;
use rustc_ast::{self as ast, LitKind, MetaItemLit, NodeId};
use rustc_ast::{self as ast, AttrStyle, LitKind, MetaItemLit, NodeId};
use rustc_errors::{DiagCtxtHandle, Diagnostic};
use rustc_feature::{AttributeTemplate, Features};
use rustc_hir::attrs::AttributeKind;
Expand Down Expand Up @@ -305,6 +305,7 @@ pub struct AcceptContext<'f, 'sess, S: Stage> {
/// The span of the attribute currently being parsed
pub(crate) attr_span: Span,

pub(crate) attr_style: AttrStyle,
/// The expected structure of the attribute.
///
/// Used in reporting errors to give a hint to users what the attribute *should* look like.
Expand Down Expand Up @@ -386,6 +387,7 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> {
i.kind.is_bytestr().then(|| self.sess().source_map().start_point(i.span))
}),
},
attr_style: self.attr_style,
})
}

Expand All @@ -396,6 +398,7 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> {
template: self.template.clone(),
attribute: self.attr_path.clone(),
reason: AttributeParseErrorReason::ExpectedIntegerLiteral,
attr_style: self.attr_style,
})
}

Expand All @@ -406,6 +409,7 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> {
template: self.template.clone(),
attribute: self.attr_path.clone(),
reason: AttributeParseErrorReason::ExpectedList,
attr_style: self.attr_style,
})
}

Expand All @@ -416,6 +420,7 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> {
template: self.template.clone(),
attribute: self.attr_path.clone(),
reason: AttributeParseErrorReason::ExpectedNoArgs,
attr_style: self.attr_style,
})
}

Expand All @@ -427,6 +432,7 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> {
template: self.template.clone(),
attribute: self.attr_path.clone(),
reason: AttributeParseErrorReason::ExpectedIdentifier,
attr_style: self.attr_style,
})
}

Expand All @@ -439,6 +445,7 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> {
template: self.template.clone(),
attribute: self.attr_path.clone(),
reason: AttributeParseErrorReason::ExpectedNameValue(name),
attr_style: self.attr_style,
})
}

Expand All @@ -450,6 +457,7 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> {
template: self.template.clone(),
attribute: self.attr_path.clone(),
reason: AttributeParseErrorReason::DuplicateKey(key),
attr_style: self.attr_style,
})
}

Expand All @@ -462,6 +470,7 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> {
template: self.template.clone(),
attribute: self.attr_path.clone(),
reason: AttributeParseErrorReason::UnexpectedLiteral,
attr_style: self.attr_style,
})
}

Expand All @@ -472,6 +481,7 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> {
template: self.template.clone(),
attribute: self.attr_path.clone(),
reason: AttributeParseErrorReason::ExpectedSingleArgument,
attr_style: self.attr_style,
})
}

Expand All @@ -482,6 +492,7 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> {
template: self.template.clone(),
attribute: self.attr_path.clone(),
reason: AttributeParseErrorReason::ExpectedAtLeastOneArgument,
attr_style: self.attr_style,
})
}

Expand All @@ -500,6 +511,7 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> {
strings: false,
list: false,
},
attr_style: self.attr_style,
})
}

Expand All @@ -518,6 +530,7 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> {
strings: false,
list: true,
},
attr_style: self.attr_style,
})
}

Expand All @@ -536,6 +549,7 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> {
strings: true,
list: false,
},
attr_style: self.attr_style,
})
}

Expand Down Expand Up @@ -735,6 +749,7 @@ impl<'sess> AttributeParser<'sess, Early> {
},
},
attr_span: attr.span,
attr_style: attr.style,
template,
attr_path: path.get_attribute_path(),
};
Expand Down Expand Up @@ -844,6 +859,7 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
emit_lint: &mut emit_lint,
},
attr_span: lower_span(attr.span),
attr_style: attr.style,
template: &accept.template,
attr_path: path.get_attribute_path(),
};
Expand Down
6 changes: 4 additions & 2 deletions compiler/rustc_attr_parsing/src/session_diagnostics.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::num::IntErrorKind;

use rustc_ast as ast;
use rustc_ast::{self as ast, AttrStyle};
use rustc_errors::codes::*;
use rustc_errors::{
Applicability, Diag, DiagArgValue, DiagCtxtHandle, Diagnostic, EmissionGuarantee, Level,
Expand Down Expand Up @@ -556,6 +556,7 @@ pub(crate) enum AttributeParseErrorReason {
pub(crate) struct AttributeParseError {
pub(crate) span: Span,
pub(crate) attr_span: Span,
pub(crate) attr_style: AttrStyle,
pub(crate) template: AttributeTemplate,
pub(crate) attribute: AttrPath,
pub(crate) reason: AttributeParseErrorReason,
Expand Down Expand Up @@ -694,7 +695,8 @@ impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for AttributeParseError {
if let Some(link) = self.template.docs {
diag.note(format!("for more information, visit <{link}>"));
}
let suggestions = self.template.suggestions(false, &name);
let suggestions = self.template.suggestions(self.attr_style, &name);

diag.span_suggestions(
self.attr_span,
if suggestions.len() == 1 {
Expand Down
8 changes: 6 additions & 2 deletions compiler/rustc_feature/src/builtin_attrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use AttributeDuplicates::*;
use AttributeGate::*;
use AttributeType::*;
use rustc_data_structures::fx::FxHashMap;
use rustc_hir::AttrStyle;
use rustc_hir::attrs::EncodeCrossCrate;
use rustc_span::edition::Edition;
use rustc_span::{Symbol, sym};
Expand Down Expand Up @@ -132,9 +133,12 @@ pub struct AttributeTemplate {
}

impl AttributeTemplate {
pub fn suggestions(&self, inner: bool, name: impl std::fmt::Display) -> Vec<String> {
pub fn suggestions(&self, style: AttrStyle, name: impl std::fmt::Display) -> Vec<String> {
let mut suggestions = vec![];
let inner = if inner { "!" } else { "" };
let inner = match style {
AttrStyle::Outer => "",
AttrStyle::Inner => "!",
};
if self.word {
suggestions.push(format!("#{inner}[{name}]"));
}
Expand Down
10 changes: 8 additions & 2 deletions compiler/rustc_lint/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ use rustc_middle::ty::layout::{LayoutError, LayoutOfHelpers, TyAndLayout};
use rustc_middle::ty::print::{PrintError, PrintTraitRefExt as _, Printer, with_no_trimmed_paths};
use rustc_middle::ty::{self, GenericArg, RegisteredTools, Ty, TyCtxt, TypingEnv, TypingMode};
use rustc_session::lint::{FutureIncompatibleInfo, Lint, LintBuffer, LintExpectationId, LintId};
use rustc_session::{LintStoreMarker, Session};
use rustc_session::{DynLintStore, Session};
use rustc_span::edit_distance::find_best_match_for_names;
use rustc_span::{Ident, Span, Symbol, sym};
use tracing::debug;
Expand Down Expand Up @@ -62,7 +62,13 @@ pub struct LintStore {
lint_groups: FxIndexMap<&'static str, LintGroup>,
}

impl LintStoreMarker for LintStore {}
impl DynLintStore for LintStore {
fn lint_groups_iter(&self) -> Box<dyn Iterator<Item = rustc_session::LintGroup> + '_> {
Box::new(self.get_lint_groups().map(|(name, lints, is_externally_loaded)| {
rustc_session::LintGroup { name, lints, is_externally_loaded }
}))
}
}

/// The target of the `by_name` map, which accounts for renaming/deprecation.
#[derive(Debug)]
Expand Down
29 changes: 27 additions & 2 deletions compiler/rustc_middle/src/lint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -211,11 +211,28 @@ impl LintExpectation {
}

fn explain_lint_level_source(
sess: &Session,
lint: &'static Lint,
level: Level,
src: LintLevelSource,
err: &mut Diag<'_, ()>,
) {
// Find the name of the lint group that contains the given lint.
// Assumes the lint only belongs to one group.
let lint_group_name = |lint| {
let lint_groups_iter = sess.lint_groups_iter();
let lint_id = LintId::of(lint);
lint_groups_iter
.filter(|lint_group| !lint_group.is_externally_loaded)
.find(|lint_group| {
lint_group
.lints
.iter()
.find(|lint_group_lint| **lint_group_lint == lint_id)
.is_some()
})
.map(|lint_group| lint_group.name)
};
let name = lint.name_lower();
if let Level::Allow = level {
// Do not point at `#[allow(compat_lint)]` as the reason for a compatibility lint
Expand All @@ -224,7 +241,15 @@ fn explain_lint_level_source(
}
match src {
LintLevelSource::Default => {
err.note_once(format!("`#[{}({})]` on by default", level.as_str(), name));
let level_str = level.as_str();
match lint_group_name(lint) {
Some(group_name) => {
err.note_once(format!("`#[{level_str}({name})]` (part of `#[{level_str}({group_name})]`) on by default"));
}
None => {
err.note_once(format!("`#[{level_str}({name})]` on by default"));
}
}
}
LintLevelSource::CommandLine(lint_flag_val, orig_level) => {
let flag = orig_level.to_cmd_flag();
Expand Down Expand Up @@ -427,7 +452,7 @@ pub fn lint_level(
decorate(&mut err);
}

explain_lint_level_source(lint, level, src, &mut err);
explain_lint_level_source(sess, lint, level, src, &mut err);
err.emit()
}
lint_level_impl(sess, lint, level, span, Box::new(decorate))
Expand Down
30 changes: 19 additions & 11 deletions compiler/rustc_parse/src/parser/cfg_select.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
use rustc_ast::token::Token;
use rustc_ast::tokenstream::{TokenStream, TokenTree};
use rustc_ast::util::classify;
use rustc_ast::{MetaItemInner, token};
use rustc_errors::PResult;
use rustc_span::Span;

use crate::exp;
use crate::parser::Parser;
use crate::parser::{AttrWrapper, ForceCollect, Parser, Restrictions, Trailing, UsePreAttrPos};

pub enum CfgSelectPredicate {
Cfg(MetaItemInner),
Expand All @@ -23,19 +24,26 @@ pub struct CfgSelectBranches {
pub unreachable: Vec<(CfgSelectPredicate, TokenStream, Span)>,
}

/// Parses a `TokenTree` that must be of the form `{ /* ... */ }`, and returns a `TokenStream` where
/// the surrounding braces are stripped.
/// Parses a `TokenTree` consisting either of `{ /* ... */ }` (and strip the braces) or an
/// expression followed by a comma (and strip the comma).
fn parse_token_tree<'a>(p: &mut Parser<'a>) -> PResult<'a, TokenStream> {
// Generate an error if the `=>` is not followed by `{`.
if p.token != token::OpenBrace {
p.expect(exp!(OpenBrace))?;
if p.token == token::OpenBrace {
// Strip the outer '{' and '}'.
match p.parse_token_tree() {
TokenTree::Token(..) => unreachable!("because of the expect above"),
TokenTree::Delimited(.., tts) => return Ok(tts),
}
}

// Strip the outer '{' and '}'.
match p.parse_token_tree() {
TokenTree::Token(..) => unreachable!("because of the expect above"),
TokenTree::Delimited(.., tts) => Ok(tts),
let expr = p.collect_tokens(None, AttrWrapper::empty(), ForceCollect::Yes, |p, _| {
p.parse_expr_res(Restrictions::STMT_EXPR, AttrWrapper::empty())
.map(|(expr, _)| (expr, Trailing::No, UsePreAttrPos::No))
})?;
if !classify::expr_is_complete(&expr) && p.token != token::CloseBrace && p.token != token::Eof {
p.expect(exp!(Comma))?;
} else {
let _ = p.eat(exp!(Comma));
}
Ok(TokenStream::from_ast(&expr))
}

pub fn parse_cfg_select<'a>(p: &mut Parser<'a>) -> PResult<'a, CfgSelectBranches> {
Expand Down
Loading
Loading