Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
cf8753e
Make `lto` and `linker-plugin-lto` work the same for `compiler_builtins`
maurer Jun 10, 2025
21de27c
Explicitly mark the end of a failed test's captured output
Zalathar Aug 27, 2025
bf6e99d
add doc-hidden to exports in attribute prelude
jdonszelmann Aug 27, 2025
ab0ee84
Add new `doc(attribute = "...")` attribute
GuillaumeGomez Jun 13, 2025
75cbd05
Add tests for `doc(attribute = "...")` attribute
GuillaumeGomez Jun 13, 2025
38e8963
Add documentation for `doc(attribute = "...")` attribute
GuillaumeGomez Jun 13, 2025
10bd61d
Create new `Item::is_fake_item` method as equivalent to check for `is…
GuillaumeGomez Jun 14, 2025
f3c0234
Add ui test for unsupported `doc(attribute = "...")` case for attribu…
GuillaumeGomez Aug 28, 2025
2c7dfa9
Add another case to the bad-lit-suffixes test
JonathanBrouwer Aug 25, 2025
f328709
Improve error messages around invalid literals in attribute arguments
JonathanBrouwer Aug 28, 2025
e0bdc46
Update uitest stderr
JonathanBrouwer Aug 28, 2025
d76cff3
Only export the sanitizer symbols for LTO and move export code to cg_…
bjorn3 Aug 28, 2025
23e72ab
Move ___asan_globals_registered export
bjorn3 Aug 28, 2025
f948c79
Rollup merge of #142472 - GuillaumeGomez:doc-attribute-attribute, r=f…
GuillaumeGomez Aug 28, 2025
9e4a283
Rollup merge of #145368 - rcvalle:rust-cfi-fix-142284, r=dianqk
GuillaumeGomez Aug 28, 2025
56c68e7
Rollup merge of #145853 - JonathanBrouwer:fix-lit-parsing, r=jdonszel…
GuillaumeGomez Aug 28, 2025
347dd47
Rollup merge of #145920 - Zalathar:failure-stdout, r=jieyouxu
GuillaumeGomez Aug 28, 2025
b944a43
Rollup merge of #145937 - jdonszelmann:doc-hidden-prelude, r=fmease
GuillaumeGomez Aug 28, 2025
a60b96a
Rollup merge of #145965 - bjorn3:sanitize_symbol_export_improvements,…
GuillaumeGomez Aug 28, 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 compiler/rustc_ast_passes/src/feature_gate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
notable_trait => doc_notable_trait
}
"meant for internal use only" {
attribute => rustdoc_internals
keyword => rustdoc_internals
fake_variadic => rustdoc_internals
search_unbox => rustdoc_internals
Expand Down
12 changes: 11 additions & 1 deletion compiler/rustc_attr_parsing/src/attributes/prelude.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,30 @@
// parsing
// templates
#[doc(hidden)]
pub(super) use rustc_feature::{AttributeTemplate, template};
// data structures
#[doc(hidden)]
pub(super) use rustc_hir::attrs::AttributeKind;
#[doc(hidden)]
pub(super) use rustc_hir::lints::AttributeLintKind;
#[doc(hidden)]
pub(super) use rustc_hir::{MethodKind, Target};
#[doc(hidden)]
pub(super) use rustc_span::{DUMMY_SP, Ident, Span, Symbol, sym};
#[doc(hidden)]
pub(super) use thin_vec::ThinVec;

#[doc(hidden)]
pub(super) use crate::attributes::{
AcceptMapping, AttributeOrder, AttributeParser, CombineAttributeParser, ConvertFn,
NoArgsAttributeParser, OnDuplicate, SingleAttributeParser,
};
// contexts
#[doc(hidden)]
pub(super) use crate::context::{AcceptContext, FinalizeContext, Stage};
#[doc(hidden)]
pub(super) use crate::parser::*;
// target checking
#[doc(hidden)]
pub(super) use crate::target_checking::Policy::{Allow, Error, Warn};
#[doc(hidden)]
pub(super) use crate::target_checking::{ALL_TARGETS, AllowedTargets};
59 changes: 36 additions & 23 deletions compiler/rustc_attr_parsing/src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ use rustc_ast::token::{self, Delimiter, MetaVarKind};
use rustc_ast::tokenstream::TokenStream;
use rustc_ast::{AttrArgs, DelimArgs, Expr, ExprKind, LitKind, MetaItemLit, NormalAttr, Path};
use rustc_ast_pretty::pprust;
use rustc_errors::PResult;
use rustc_errors::{Diag, PResult};
use rustc_hir::{self as hir, AttrPath};
use rustc_parse::exp;
use rustc_parse::parser::{Parser, PathStyle, token_descr};
use rustc_session::errors::report_lit_error;
use rustc_session::errors::{create_lit_error, report_lit_error};
use rustc_session::parse::ParseSess;
use rustc_span::{ErrorGuaranteed, Ident, Span, Symbol, sym};
use thin_vec::ThinVec;
Expand Down Expand Up @@ -379,22 +379,23 @@ struct MetaItemListParserContext<'a, 'sess> {

impl<'a, 'sess> MetaItemListParserContext<'a, 'sess> {
fn parse_unsuffixed_meta_item_lit(&mut self) -> PResult<'sess, MetaItemLit> {
let uninterpolated_span = self.parser.token_uninterpolated_span();
let Some(token_lit) = self.parser.eat_token_lit() else {
return self.parser.handle_missing_lit(Parser::mk_meta_item_lit_char);
};
let Some(token_lit) = self.parser.eat_token_lit() else { return Err(self.expected_lit()) };
self.unsuffixed_meta_item_from_lit(token_lit)
}

fn unsuffixed_meta_item_from_lit(
&mut self,
token_lit: token::Lit,
) -> PResult<'sess, MetaItemLit> {
let lit = match MetaItemLit::from_token_lit(token_lit, self.parser.prev_token.span) {
Ok(lit) => lit,
Err(err) => {
let guar =
report_lit_error(&self.parser.psess, err, token_lit, uninterpolated_span);
// Pack possible quotes and prefixes from the original literal into
// the error literal's symbol so they can be pretty-printed faithfully.
let suffixless_lit = token::Lit::new(token_lit.kind, token_lit.symbol, None);
let symbol = Symbol::intern(&suffixless_lit.to_string());
let token_lit = token::Lit::new(token::Err(guar), symbol, token_lit.suffix);
MetaItemLit::from_token_lit(token_lit, uninterpolated_span).unwrap()
return Err(create_lit_error(
&self.parser.psess,
err,
token_lit,
self.parser.prev_token_uninterpolated_span(),
));
}
};

Expand Down Expand Up @@ -448,16 +449,28 @@ impl<'a, 'sess> MetaItemListParserContext<'a, 'sess> {
}

fn parse_meta_item_inner(&mut self) -> PResult<'sess, MetaItemOrLitParser<'static>> {
match self.parse_unsuffixed_meta_item_lit() {
Ok(lit) => return Ok(MetaItemOrLitParser::Lit(lit)),
Err(err) => err.cancel(), // we provide a better error below
}

match self.parse_attr_item() {
Ok(mi) => return Ok(MetaItemOrLitParser::MetaItemParser(mi)),
Err(err) => err.cancel(), // we provide a better error below
if let Some(token_lit) = self.parser.eat_token_lit() {
// If a literal token is parsed, we commit to parsing a MetaItemLit for better errors
Ok(MetaItemOrLitParser::Lit(self.unsuffixed_meta_item_from_lit(token_lit)?))
} else {
let prev_pros = self.parser.approx_token_stream_pos();
match self.parse_attr_item() {
Ok(item) => Ok(MetaItemOrLitParser::MetaItemParser(item)),
Err(err) => {
// If `parse_attr_item` made any progress, it likely has a more precise error we should prefer
// If it didn't make progress we use the `expected_lit` from below
if self.parser.approx_token_stream_pos() != prev_pros {
Err(err)
} else {
err.cancel();
Err(self.expected_lit())
}
}
}
}
}

fn expected_lit(&mut self) -> Diag<'sess> {
let mut err = InvalidMetaItem {
span: self.parser.token.span,
descr: token_descr(&self.parser.token),
Expand Down Expand Up @@ -492,7 +505,7 @@ impl<'a, 'sess> MetaItemListParserContext<'a, 'sess> {
self.parser.bump();
}

Err(self.parser.dcx().create_err(err))
self.parser.dcx().create_err(err)
}

fn parse(
Expand Down
32 changes: 32 additions & 0 deletions compiler/rustc_codegen_llvm/src/back/lto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ use rustc_codegen_ssa::{ModuleCodegen, ModuleKind, looks_like_rust_object_file};
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::memmap::Mmap;
use rustc_errors::DiagCtxtHandle;
use rustc_hir::attrs::SanitizerSet;
use rustc_middle::bug;
use rustc_middle::dep_graph::WorkProduct;
use rustc_session::config::{self, Lto};
Expand Down Expand Up @@ -42,6 +43,37 @@ fn prepare_lto(
.map(|symbol| CString::new(symbol.to_owned()).unwrap())
.collect::<Vec<CString>>();

if cgcx.regular_module_config.instrument_coverage
|| cgcx.regular_module_config.pgo_gen.enabled()
{
// These are weak symbols that point to the profile version and the
// profile name, which need to be treated as exported so LTO doesn't nix
// them.
const PROFILER_WEAK_SYMBOLS: [&CStr; 2] =
[c"__llvm_profile_raw_version", c"__llvm_profile_filename"];

symbols_below_threshold.extend(PROFILER_WEAK_SYMBOLS.iter().map(|&sym| sym.to_owned()));
}

if cgcx.regular_module_config.sanitizer.contains(SanitizerSet::MEMORY) {
let mut msan_weak_symbols = Vec::new();

// Similar to profiling, preserve weak msan symbol during LTO.
if cgcx.regular_module_config.sanitizer_recover.contains(SanitizerSet::MEMORY) {
msan_weak_symbols.push(c"__msan_keep_going");
}

if cgcx.regular_module_config.sanitizer_memory_track_origins != 0 {
msan_weak_symbols.push(c"__msan_track_origins");
}

symbols_below_threshold.extend(msan_weak_symbols.into_iter().map(|sym| sym.to_owned()));
}

// Preserve LLVM-injected, ASAN-related symbols.
// See also https://github.com/rust-lang/rust/issues/113404.
symbols_below_threshold.push(c"___asan_globals_registered".to_owned());

// __llvm_profile_counter_bias is pulled in at link time by an undefined reference to
// __llvm_profile_runtime, therefore we won't know until link time if this symbol
// should have default visibility.
Expand Down
49 changes: 1 addition & 48 deletions compiler/rustc_codegen_ssa/src/back/symbol_export.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use rustc_middle::ty::{self, GenericArgKind, GenericArgsRef, Instance, SymbolNam
use rustc_middle::util::Providers;
use rustc_session::config::{CrateType, OomStrategy};
use rustc_symbol_mangling::mangle_internal_symbol;
use rustc_target::spec::{SanitizerSet, TlsModel};
use rustc_target::spec::TlsModel;
use tracing::debug;

use crate::base::allocator_kind_for_codegen;
Expand Down Expand Up @@ -242,53 +242,6 @@ fn exported_non_generic_symbols_provider_local<'tcx>(
}
}

if tcx.sess.instrument_coverage() || tcx.sess.opts.cg.profile_generate.enabled() {
// These are weak symbols that point to the profile version and the
// profile name, which need to be treated as exported so LTO doesn't nix
// them.
const PROFILER_WEAK_SYMBOLS: [&str; 2] =
["__llvm_profile_raw_version", "__llvm_profile_filename"];

symbols.extend(PROFILER_WEAK_SYMBOLS.iter().map(|sym| {
let exported_symbol = ExportedSymbol::NoDefId(SymbolName::new(tcx, sym));
(
exported_symbol,
SymbolExportInfo {
level: SymbolExportLevel::C,
kind: SymbolExportKind::Data,
used: false,
rustc_std_internal_symbol: false,
},
)
}));
}

if tcx.sess.opts.unstable_opts.sanitizer.contains(SanitizerSet::MEMORY) {
let mut msan_weak_symbols = Vec::new();

// Similar to profiling, preserve weak msan symbol during LTO.
if tcx.sess.opts.unstable_opts.sanitizer_recover.contains(SanitizerSet::MEMORY) {
msan_weak_symbols.push("__msan_keep_going");
}

if tcx.sess.opts.unstable_opts.sanitizer_memory_track_origins != 0 {
msan_weak_symbols.push("__msan_track_origins");
}

symbols.extend(msan_weak_symbols.into_iter().map(|sym| {
let exported_symbol = ExportedSymbol::NoDefId(SymbolName::new(tcx, sym));
(
exported_symbol,
SymbolExportInfo {
level: SymbolExportLevel::C,
kind: SymbolExportKind::Data,
used: false,
rustc_std_internal_symbol: false,
},
)
}));
}

// Sort so we get a stable incr. comp. hash.
symbols.sort_by_cached_key(|s| s.0.symbol_name_for_local_instance(tcx));

Expand Down
13 changes: 1 addition & 12 deletions compiler/rustc_codegen_ssa/src/back/write.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,23 +138,12 @@ impl ModuleConfig {

let emit_obj = if !should_emit_obj {
EmitObj::None
} else if sess.target.obj_is_bitcode
|| (sess.opts.cg.linker_plugin_lto.enabled() && !no_builtins)
{
} else if sess.target.obj_is_bitcode || sess.opts.cg.linker_plugin_lto.enabled() {
// This case is selected if the target uses objects as bitcode, or
// if linker plugin LTO is enabled. In the linker plugin LTO case
// the assumption is that the final link-step will read the bitcode
// and convert it to object code. This may be done by either the
// native linker or rustc itself.
//
// Note, however, that the linker-plugin-lto requested here is
// explicitly ignored for `#![no_builtins]` crates. These crates are
// specifically ignored by rustc's LTO passes and wouldn't work if
// loaded into the linker. These crates define symbols that LLVM
// lowers intrinsics to, and these symbol dependencies aren't known
// until after codegen. As a result any crate marked
// `#![no_builtins]` is assumed to not participate in LTO and
// instead goes on to generate object code.
EmitObj::Bitcode
} else if need_bitcode_in_object(tcx) {
EmitObj::ObjectCode(BitcodeSection::Full)
Expand Down
6 changes: 0 additions & 6 deletions compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1226,12 +1226,6 @@ extern "C" void LLVMRustPrintPasses() {
extern "C" void LLVMRustRunRestrictionPass(LLVMModuleRef M, char **Symbols,
size_t Len) {
auto PreserveFunctions = [=](const GlobalValue &GV) {
// Preserve LLVM-injected, ASAN-related symbols.
// See also https://github.com/rust-lang/rust/issues/113404.
if (GV.getName() == "___asan_globals_registered") {
return true;
}

// Preserve symbols exported from Rust modules.
for (size_t I = 0; I < Len; I++) {
if (GV.getName() == Symbols[I]) {
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_parse/src/parser/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2077,7 +2077,7 @@ impl<'a> Parser<'a> {
(token::Lit { symbol: name, suffix: None, kind: token::Char }, span)
}

pub fn mk_meta_item_lit_char(name: Symbol, span: Span) -> MetaItemLit {
fn mk_meta_item_lit_char(name: Symbol, span: Span) -> MetaItemLit {
ast::MetaItemLit {
symbol: name,
suffix: None,
Expand All @@ -2086,7 +2086,7 @@ impl<'a> Parser<'a> {
}
}

pub fn handle_missing_lit<L>(
fn handle_missing_lit<L>(
&mut self,
mk_lit_char: impl FnOnce(Symbol, Span) -> L,
) -> PResult<'a, L> {
Expand Down
14 changes: 9 additions & 5 deletions compiler/rustc_passes/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,10 @@ passes_doc_alias_start_end =
passes_doc_attr_not_crate_level =
`#![doc({$attr_name} = "...")]` isn't allowed as a crate-level attribute

passes_doc_attribute_not_attribute =
nonexistent builtin attribute `{$attribute}` used in `#[doc(attribute = "...")]`
.help = only existing builtin attributes are allowed in core/std

passes_doc_cfg_hide_takes_list =
`#[doc(cfg_hide(...))]` takes a list of attributes

Expand Down Expand Up @@ -173,16 +177,16 @@ passes_doc_inline_only_use =
passes_doc_invalid =
invalid `doc` attribute

passes_doc_keyword_empty_mod =
`#[doc(keyword = "...")]` should be used on empty modules
passes_doc_keyword_attribute_empty_mod =
`#[doc({$attr_name} = "...")]` should be used on empty modules

passes_doc_keyword_attribute_not_mod =
`#[doc({$attr_name} = "...")]` should be used on modules

passes_doc_keyword_not_keyword =
nonexistent keyword `{$keyword}` used in `#[doc(keyword = "...")]`
.help = only existing keywords are allowed in core/std

passes_doc_keyword_not_mod =
`#[doc(keyword = "...")]` should be used on modules

passes_doc_keyword_only_impl =
`#[doc(keyword = "...")]` should be used on impl blocks

Expand Down
Loading
Loading