Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
5ed5b26
Add Command::get_resolved_envs
schneems Nov 26, 2025
d0ea88e
error on empty `export_name`
folkertdev Apr 19, 2026
c08b9ab
validate link name parameter
folkertdev Apr 26, 2026
fd2e542
Add regression test for issue 144329
DaniPopes Apr 12, 2026
7eb6a20
Update a bunch of bootstrap dependencies to remove windows-target
bjorn3 Apr 30, 2026
a80af22
remove turbofish notation + use None / Some instead of Option::
Cheese-Space May 3, 2026
09dc7fc
mark some panicking methods around Duration as track_caller
RalfJung May 4, 2026
d0eab57
Change `SwitchInt` handling in dataflow analysis.
nnethercote Apr 29, 2026
a275453
replace leftover call to ArgParser::list with AcceptContext::expect_lits
scrabsha May 8, 2026
9097f5b
rustc_attr_parsing: improve error message for codegen attributes
scrabsha May 8, 2026
dcdba78
rustc_attr_parsing: add AcceptContext::expect_string_literal
scrabsha May 8, 2026
40da877
Add `str::word_to_titlecase()` to `alloc`
Jules-Bertholet May 9, 2026
f4adc40
Add mention of sendfile(2) and splice(2) to fs::copy() documentation.
tomilepp May 9, 2026
17977f3
Rollup merge of #149362 - schneems:schneems/get_resolved_envs, r=Mark…
matthiaskrgr May 10, 2026
2728204
Rollup merge of #155705 - Jules-Bertholet:word-to-titlecase, r=Mark-S…
matthiaskrgr May 10, 2026
9165dbf
Rollup merge of #155970 - tomilepp:issue-155968-fix, r=joshtriplett
matthiaskrgr May 10, 2026
0711aa9
Rollup merge of #156006 - bjorn3:bootstrap_no_import_libs, r=Mark-Sim…
matthiaskrgr May 10, 2026
02f733b
Rollup merge of #156169 - nnethercote:simplify-SwitchInt-stuff, r=cjg…
matthiaskrgr May 10, 2026
dd0746b
Rollup merge of #155188 - DaniPopes:144329-test, r=Mark-Simulacrum
matthiaskrgr May 10, 2026
6b93655
Rollup merge of #155515 - folkertdev:export-name-not-empty, r=jdonsze…
matthiaskrgr May 10, 2026
99abbd6
Rollup merge of #155817 - folkertdev:link-name-null-empty, r=mejrs
matthiaskrgr May 10, 2026
6fffff9
Rollup merge of #156107 - Cheese-Space:patch-1, r=Mark-Simulacrum
matthiaskrgr May 10, 2026
3401857
Rollup merge of #156133 - RalfJung:time-panic-track-caller, r=Mark-Si…
matthiaskrgr May 10, 2026
ddecb76
Rollup merge of #156363 - scrabsha:attributes/expect-string-literal, …
matthiaskrgr May 10, 2026
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
2 changes: 1 addition & 1 deletion compiler/rustc_ast/src/attr/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -845,7 +845,7 @@ pub fn list_contains_name(items: &[MetaItemInner], name: Symbol) -> bool {
}

impl MetaItemLit {
pub fn value_str(&self) -> Option<Symbol> {
pub fn value_as_str(&self) -> Option<Symbol> {
LitKind::from_token_lit(self.as_token_lit()).ok().and_then(|lit| lit.str())
}
}
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_attr_parsing/src/attributes/cfg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,12 +135,12 @@ fn parse_cfg_entry_version(
cx.emit_err(session_diagnostics::ExpectedSingleVersionLiteral { span: list.span })
);
};
let Some(version_lit) = version.lit() else {
let Some(version_lit) = version.as_lit() else {
return Err(
cx.emit_err(session_diagnostics::ExpectedVersionLiteral { span: version.span() })
);
};
let Some(version_str) = version_lit.value_str() else {
let Some(version_str) = version_lit.value_as_str() else {
return Err(
cx.emit_err(session_diagnostics::ExpectedVersionLiteral { span: version_lit.span })
);
Expand Down
5 changes: 1 addition & 4 deletions compiler/rustc_attr_parsing/src/attributes/cfi_encoding.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,7 @@ impl SingleAttributeParser for CfiEncodingParser {
fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<AttributeKind> {
let name_value = cx.expect_name_value(args, cx.attr_span, Some(sym::cfi_encoding))?;

let Some(value_str) = name_value.value_as_str() else {
cx.adcx().expected_string_literal(name_value.value_span, None);
return None;
};
let value_str = cx.expect_string_literal(name_value)?;

if value_str.as_str().trim().is_empty() {
cx.adcx().expected_non_empty_string_literal(name_value.value_span);
Expand Down
24 changes: 14 additions & 10 deletions compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ use rustc_span::edition::Edition::Edition2024;
use super::prelude::*;
use crate::attributes::AttributeSafety;
use crate::session_diagnostics::{
NakedFunctionIncompatibleAttribute, NullOnExport, NullOnObjcClass, NullOnObjcSelector,
ObjcClassExpectedStringLiteral, ObjcSelectorExpectedStringLiteral,
EmptyExportName, NakedFunctionIncompatibleAttribute, NullOnExport, NullOnObjcClass,
NullOnObjcSelector, ObjcClassExpectedStringLiteral, ObjcSelectorExpectedStringLiteral,
};
use crate::target_checking::Policy::AllowSilent;

Expand Down Expand Up @@ -119,16 +119,19 @@ impl SingleAttributeParser for ExportNameParser {

fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<AttributeKind> {
let nv = cx.expect_name_value(args, cx.attr_span, None)?;
let Some(name) = nv.value_as_str() else {
cx.adcx().expected_string_literal(nv.value_span, Some(nv.value_as_lit()));
return None;
};
let name = cx.expect_string_literal(nv)?;
if name.as_str().contains('\0') {
// `#[export_name = ...]` will be converted to a null-terminated string,
// so it may not contain any null characters.
cx.emit_err(NullOnExport { span: cx.attr_span });
return None;
}
if name.is_empty() {
// LLVM will make up a name if the empty string is given, but that name will be
// inconsistent between compilation units, causing linker errors.
cx.emit_err(EmptyExportName { span: cx.attr_span });
return None;
}
Some(AttributeKind::ExportName { name, span: cx.attr_span })
}
}
Expand Down Expand Up @@ -478,8 +481,7 @@ fn parse_tf_attribute(
}

// Use value
let Some(value_str) = value.value_as_str() else {
cx.adcx().expected_string_literal(value.value_span, Some(value.value_as_lit()));
let Some(value_str) = cx.expect_string_literal(value) else {
return features;
};
for feature in value_str.as_str().split(",") {
Expand Down Expand Up @@ -594,8 +596,10 @@ impl SingleAttributeParser for SanitizeParser {
return;
}
None => {
cx.adcx()
.expected_string_literal(value.value_span, Some(value.value_as_lit()));
cx.adcx().expected_specific_argument_strings(
value.value_span,
&[sym::on, sym::off],
);
return;
}
};
Expand Down
5 changes: 1 addition & 4 deletions compiler/rustc_attr_parsing/src/attributes/confusables.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,7 @@ impl AttributeParser for ConfusablesParser {
}

for param in list.mixed() {
let span = param.span();

let Some(lit) = param.lit().and_then(|i| i.value_str()) else {
cx.adcx().expected_string_literal(span, param.lit());
let Some(lit) = cx.expect_string_literal(param) else {
continue;
};

Expand Down
10 changes: 2 additions & 8 deletions compiler/rustc_attr_parsing/src/attributes/crate_level.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,7 @@ impl SingleAttributeParser for CrateNameParser {
fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<AttributeKind> {
let n = cx.expect_name_value(args, cx.attr_span, None)?;

let Some(name) = n.value_as_str() else {
cx.adcx().expected_string_literal(n.value_span, Some(n.value_as_lit()));
return None;
};
let name = cx.expect_string_literal(n)?;

Some(AttributeKind::CrateName { name, name_span: n.value_span, attr_span: cx.attr_span })
}
Expand All @@ -44,10 +41,7 @@ impl CombineAttributeParser for CrateTypeParser {
) -> impl IntoIterator<Item = Self::Item> {
let n = cx.expect_name_value(args, cx.attr_span, None)?;

let Some(crate_type) = n.value_as_str() else {
cx.adcx().expected_string_literal(n.value_span, Some(n.value_as_lit()));
return None;
};
let crate_type = cx.expect_string_literal(n)?;

let Ok(crate_type) = crate_type.try_into() else {
// We don't error on invalid `#![crate_type]` when not applied to a crate
Expand Down
5 changes: 1 addition & 4 deletions compiler/rustc_attr_parsing/src/attributes/debugger.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,7 @@ impl CombineAttributeParser for DebuggerViualizerParser {
}
};

let Some(path) = args.value_as_str() else {
cx.adcx().expected_string_literal(args.value_span, Some(args.value_as_lit()));
return None;
};
let path = cx.expect_string_literal(args)?;

Some(DebugVisualizer { span: ident.span.to(args.value_span), visualizer_type, path })
}
Expand Down
6 changes: 2 additions & 4 deletions compiler/rustc_attr_parsing/src/attributes/doc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -255,17 +255,15 @@ impl DocParser {
}
ArgParser::List(list) => {
for i in list.mixed() {
let Some(alias) = i.lit().and_then(|i| i.value_str()) else {
cx.adcx().expected_string_literal(i.span(), i.lit());
let Some(alias) = cx.expect_string_literal(i) else {
continue;
};

self.add_alias(cx, alias, i.span());
}
}
ArgParser::NameValue(nv) => {
let Some(alias) = nv.value_as_str() else {
cx.adcx().expected_string_literal(nv.value_span, Some(nv.value_as_lit()));
let Some(alias) = cx.expect_string_literal(nv) else {
return;
};
self.add_alias(cx, alias, nv.value_span);
Expand Down
14 changes: 2 additions & 12 deletions compiler/rustc_attr_parsing/src/attributes/inline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,21 +77,11 @@ impl SingleAttributeParser for RustcForceInlineParser {
ArgParser::List(list) => {
let l = cx.expect_single(list)?;

let Some(reason) = l.lit().and_then(|i| i.kind.str()) else {
cx.adcx().expected_string_literal(l.span(), l.lit());
return None;
};

Some(reason)
}
ArgParser::NameValue(v) => {
let Some(reason) = v.value_as_str() else {
cx.adcx().expected_string_literal(v.value_span, Some(v.value_as_lit()));
return None;
};
let reason = cx.expect_string_literal(l)?;

Some(reason)
}
ArgParser::NameValue(v) => cx.expect_string_literal(v),
};

Some(AttributeKind::Inline(
Expand Down
54 changes: 26 additions & 28 deletions compiler/rustc_attr_parsing/src/attributes/link_attrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use crate::session_diagnostics::{
AsNeededCompatibility, BundleNeedsStatic, EmptyLinkName, ExportSymbolsNeedsStatic,
ImportNameTypeRaw, ImportNameTypeX86, IncompatibleWasmLink, InvalidLinkModifier,
InvalidMachoSection, InvalidMachoSectionReason, LinkFrameworkApple, LinkOrdinalOutOfRange,
LinkRequiresName, MultipleModifiers, NullOnLinkSection, RawDylibNoNul, RawDylibOnlyWindows,
LinkRequiresName, MultipleModifiers, NullOnLinkName, NullOnLinkSection, RawDylibOnlyWindows,
WholeArchiveNeedsStatic,
};

Expand All @@ -37,10 +37,20 @@ impl SingleAttributeParser for LinkNameParser {

fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<AttributeKind> {
let nv = cx.expect_name_value(args, cx.attr_span, None)?;
let Some(name) = nv.value_as_str() else {
cx.adcx().expected_string_literal(nv.value_span, Some(nv.value_as_lit()));
let name = cx.expect_string_literal(nv)?;

if name.as_str().contains('\0') {
// `#[link_name = ...]` will be converted to a null-terminated string,
// so it may not contain any null characters.
cx.emit_err(NullOnLinkName { span: nv.value_span });
return None;
};
}
if name.is_empty() {
// Otherwise LLVM will just make up a name and the linker will fail
// to find an empty symbol name.
cx.emit_err(EmptyLinkName { span: nv.value_span });
return None;
}

Some(LinkName { name, span: cx.attr_span })
}
Expand Down Expand Up @@ -218,7 +228,7 @@ impl CombineAttributeParser for LinkParser {
if wasm_import_module.is_some() {
(name, kind) = (wasm_import_module, Some(NativeLibKind::WasmImportModule));
}
let Some((name, name_span)) = name else {
let Some((name, _name_span)) = name else {
cx.emit_err(LinkRequiresName { span: cx.attr_span });
return None;
};
Expand All @@ -230,12 +240,6 @@ impl CombineAttributeParser for LinkParser {
}
}

if let Some(NativeLibKind::RawDylib { .. }) = kind
&& name.as_str().contains('\0')
{
cx.emit_err(RawDylibNoNul { span: name_span });
}

Some(LinkEntry {
span: cx.attr_span,
kind: kind.unwrap_or(NativeLibKind::Unspecified),
Expand All @@ -260,14 +264,17 @@ impl LinkParser {
let Some(nv) = cx.expect_name_value(item.args(), item.span(), Some(sym::name)) else {
return false;
};
let Some(link_name) = nv.value_as_str() else {
cx.adcx().expected_string_literal(nv.args_span(), Some(nv.value_as_lit()));
let Some(link_name) = cx.expect_string_literal(nv) else {
return false;
};

if link_name.as_str().contains('\0') {
cx.emit_err(NullOnLinkName { span: nv.value_span });
}
if link_name.is_empty() {
cx.emit_err(EmptyLinkName { span: nv.value_span });
}

*name = Some((link_name, nv.value_span));
true
}
Expand All @@ -286,8 +293,7 @@ impl LinkParser {
let Some(nv) = cx.expect_name_value(item.args(), item.span(), Some(sym::kind)) else {
return true;
};
let Some(link_kind) = nv.value_as_str() else {
cx.adcx().expected_string_literal(item.span(), Some(nv.value_as_lit()));
let Some(link_kind) = cx.expect_string_literal(nv) else {
return true;
};

Expand Down Expand Up @@ -365,8 +371,7 @@ impl LinkParser {
let Some(nv) = cx.expect_name_value(item.args(), item.span(), Some(sym::modifiers)) else {
return true;
};
let Some(link_modifiers) = nv.value_as_str() else {
cx.adcx().expected_string_literal(item.span(), Some(nv.value_as_lit()));
let Some(link_modifiers) = cx.expect_string_literal(nv) else {
return true;
};
*modifiers = Some((link_modifiers, nv.value_span));
Expand Down Expand Up @@ -408,8 +413,7 @@ impl LinkParser {
else {
return true;
};
let Some(link_wasm_import_module) = nv.value_as_str() else {
cx.adcx().expected_string_literal(item.span(), Some(nv.value_as_lit()));
let Some(link_wasm_import_module) = cx.expect_string_literal(nv) else {
return true;
};
*wasm_import_module = Some((link_wasm_import_module, item.span()));
Expand All @@ -429,8 +433,7 @@ impl LinkParser {
else {
return true;
};
let Some(link_import_name_type) = nv.value_as_str() else {
cx.adcx().expected_string_literal(nv.value_span, Some(nv.value_as_lit()));
let Some(link_import_name_type) = cx.expect_string_literal(nv) else {
return true;
};
if cx.sess().target.arch != Arch::X86 {
Expand Down Expand Up @@ -498,10 +501,7 @@ impl SingleAttributeParser for LinkSectionParser {

fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<AttributeKind> {
let nv = cx.expect_name_value(args, cx.attr_span, None)?;
let Some(name) = nv.value_as_str() else {
cx.adcx().expected_string_literal(nv.value_span, Some(nv.value_as_lit()));
return None;
};
let name = cx.expect_string_literal(nv)?;
if name.as_str().contains('\0') {
// `#[link_section = ...]` will be converted to a null-terminated string,
// so it may not contain any null characters.
Expand Down Expand Up @@ -630,9 +630,7 @@ impl SingleAttributeParser for LinkageParser {
fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<AttributeKind> {
let name_value = cx.expect_name_value(args, cx.attr_span, Some(sym::linkage))?;

let Some(value) = name_value.value_as_str() else {
cx.adcx()
.expected_string_literal(name_value.value_span, Some(name_value.value_as_lit()));
let Some(value) = cx.expect_string_literal(name_value) else {
return None;
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,7 @@ impl SingleAttributeParser for MustNotSuspendParser {

fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<AttributeKind> {
let reason = match args {
ArgParser::NameValue(reason) => match reason.value_as_str() {
Some(val) => Some(val),
None => {
cx.adcx().expected_nv_or_no_args(reason.value_span);
return None;
}
},
ArgParser::NameValue(reason) => cx.expect_string_literal(reason),
ArgParser::NoArgs => None,
ArgParser::List(list) => {
cx.adcx().expected_nv_or_no_args(list.span);
Expand Down
11 changes: 1 addition & 10 deletions compiler/rustc_attr_parsing/src/attributes/must_use.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,16 +30,7 @@ impl SingleAttributeParser for MustUseParser {
span: cx.attr_span,
reason: match args {
ArgParser::NoArgs => None,
ArgParser::NameValue(name_value) => {
let Some(value_str) = name_value.value_as_str() else {
cx.adcx().expected_string_literal(
name_value.value_span,
Some(&name_value.value_as_lit()),
);
return None;
};
Some(value_str)
}
ArgParser::NameValue(name_value) => cx.expect_string_literal(name_value),
ArgParser::List(list) => {
cx.adcx().expected_nv_or_no_args(list.span);
return None;
Expand Down
5 changes: 1 addition & 4 deletions compiler/rustc_attr_parsing/src/attributes/path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,7 @@ impl SingleAttributeParser for PathParser {

fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<AttributeKind> {
let nv = cx.expect_name_value(args, cx.attr_span, None)?;
let Some(path) = nv.value_as_str() else {
cx.adcx().expected_string_literal(nv.value_span, Some(nv.value_as_lit()));
return None;
};
let path = cx.expect_string_literal(nv)?;

Some(AttributeKind::Path(path))
}
Expand Down
3 changes: 1 addition & 2 deletions compiler/rustc_attr_parsing/src/attributes/prototype.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,7 @@ fn extract_value(
return;
}

let Some(value_sym) = val.value_as_str() else {
cx.adcx().expected_string_literal(val.value_span, Some(val.value_as_lit()));
let Some(value_sym) = cx.expect_string_literal(val) else {
*failed = true;
return;
};
Expand Down
Loading
Loading