Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
73 commits
Select commit Hold shift + click to select a range
3ffc0fb
rustdoc: warn on improperly interleaved HTML/MD
notriddle Jul 2, 2026
cb61eb4
rustdoc: add tests for MD/HTML interleaving
notriddle Jul 2, 2026
c9be91c
Clean up and test paragraph and table warn
notriddle Jul 9, 2026
9bc15a8
html_tags: remove `in_code_block` no-op branch
notriddle Jul 16, 2026
047068a
html_tags: rename tags based on camelid's nit
notriddle Jul 16, 2026
fe11f5e
rustdoc: lint MD in HTML script/style
notriddle Jul 16, 2026
1e452c3
Fix(lib/fs/win): Fall back on Win32 delete for Dir::remove_file
PaulDance Jul 17, 2026
f2476c5
Normalize next-gen region constraints
Dnreikronos Jun 25, 2026
cb0e874
Add regression test for object candidates
Dnreikronos Jun 25, 2026
30895ee
Preserve normalized solver region constraints
Dnreikronos Jul 21, 2026
f754b53
Normalize eagerly handled region constraints
Dnreikronos Jul 21, 2026
66d0fb8
stepping into `NormalizesTo` where-clauses may be productive
lcnr Apr 16, 2026
4233b3b
Collect constants within `global_asm!` in collector
nbdd0121 Mar 12, 2025
f44536c
Add FnDef/Closure -> FnPtr coercion for inline asm const operand
nbdd0121 Dec 5, 2025
bf74b6c
Give global_asm symbol names
nbdd0121 Dec 15, 2025
b44bea2
Delay stringification of const to backend
nbdd0121 Dec 18, 2025
ca40339
Unify handling of asm const and sym using CTFE
nbdd0121 Dec 18, 2025
4c39d62
Unify handling of `GlobalAlloc` inside backend
nbdd0121 Dec 19, 2025
338d560
Handle pointers with offset for asm const
nbdd0121 Dec 18, 2025
6deaed5
Support codegen of asm const pointers without provenance
nbdd0121 Dec 18, 2025
1fd34e4
Give codegen units symbol names that backend can use
nbdd0121 Jun 10, 2026
c95d35e
Generate unique symbol names if const pointers refer to promoted static
nbdd0121 Dec 19, 2025
aabf824
optimization: don't look for diagnostic/canonical items without rustc…
mejrs Jul 22, 2026
e3712ee
x test cargo-miri: run all subcrate tests as well
RalfJung Jul 22, 2026
8ed6fff
Previously both free functions and associated functions creates a FnD…
Shourya742 Jul 11, 2026
ff7f240
emit error for both AssocFn and Fn const lowering and add fixme
Shourya742 Jul 23, 2026
421d5f5
bless the fallout
Shourya742 Jul 23, 2026
8242b33
document #[global_allocator] constraints
RalfJung Jul 22, 2026
73ff59f
Implement asm_const_ptr feature
nbdd0121 Oct 24, 2024
5d22dac
Add test if asm const are MIR inlined and monomorphized twice
nbdd0121 Apr 22, 2026
0316085
Expand invalid-const-operand test case to cover &str and &CStr
nbdd0121 Jul 22, 2026
a14d50a
rustdoc-js: ignore editor temp files in test folder discovery
AayushMainali-Github Jul 23, 2026
af56582
Avoid `#[target_features]`
nnethercote Jul 24, 2026
ef765ba
rustdoc: use `to_ascii_lowercase` for HTML tags
notriddle Jul 24, 2026
ef33862
rustdoc: helper method for generating doc comments
notriddle Jul 24, 2026
158fdbf
when bailing on ambiguity, don't force other results to ambig
lcnr Apr 28, 2026
f176d8b
std::sync::poison: disable auto_cfg on PoisonError::new
Vastargazing Jul 24, 2026
8aafa5e
[rustdoc] Correctly handle output options with `--show-coverage`
GuillaumeGomez Jul 16, 2026
f545db6
Add regression test for `--show-coverage` output
GuillaumeGomez Jul 16, 2026
65b6e98
Add small message to say where the output was generated
GuillaumeGomez Jul 16, 2026
854bbe7
Fix `tests/run-make/rustdoc-show-coverage/rmake.rs` by requiring `nee…
GuillaumeGomez Jul 23, 2026
098056a
Move `rustdoc-ui` `--show-coverage` tests into the `coverage` folder
GuillaumeGomez Jul 24, 2026
f8711a1
reuse regular exported_non_generic_symbols logic in Miri
RalfJung Jul 22, 2026
c680b50
Mention how the `-o` option behaves with the `--show-coverage` option
GuillaumeGomez Jul 24, 2026
cdad583
Added implementation on set_permissions_nofollow for all platforms su…
asder8215 Jun 20, 2026
4bd52e9
Remove redundant `#[rustc_paren_sugar]` feature gate
mejrs Jul 24, 2026
1a4a07e
Use dylib build in distcheck
nikic Jul 24, 2026
2dc6470
add `FnHeader::span`
folkertdev Jul 23, 2026
b16960f
make `ident` optional in `check_extern_fn_signature`
folkertdev Jul 23, 2026
180f48d
add `BorrowedFnSig` to prevent a clone down the road
folkertdev Jul 23, 2026
f7a98cb
add `FnPtrTy::header`
folkertdev Jul 23, 2026
152ac58
run ABI checks on function pointer types
folkertdev Jul 23, 2026
55c729f
disallow `!` (i.e. `Never`) as a `extern "custom"` return type
folkertdev Jul 23, 2026
a2c59e9
test `extern "custom"` restrictions on function pointers
folkertdev Jul 23, 2026
d0dde60
improve suggestion when `safe` is used on function pointers
folkertdev Jul 23, 2026
51ae4b5
Rollup merge of #159847 - nikic:distcheck-shared, r=Kobzol
jhpratt Jul 24, 2026
a001ebe
Rollup merge of #158168 - asder8215:windows_set_permissions_nofollow,…
jhpratt Jul 24, 2026
a70c4dd
Rollup merge of #138618 - nbdd0121:asm_const_ptr, r=bjorn3
jhpratt Jul 24, 2026
c34a4eb
Rollup merge of #157962 - Shourya742:2026-06-16-function-x-cannot-be-…
jhpratt Jul 24, 2026
06ae700
Rollup merge of #158404 - Dnreikronos:trait_solver/canonicalize_next_…
jhpratt Jul 24, 2026
ab1da99
Rollup merge of #158709 - notriddle:html-lint-interleaving, r=camelid…
jhpratt Jul 24, 2026
11a3a85
Rollup merge of #159720 - RalfJung:global-allocator-opsem-magic, r=aa…
jhpratt Jul 24, 2026
bb50266
Rollup merge of #159732 - mejrs:attribute_crawler, r=nnethercote
jhpratt Jul 24, 2026
ac3f45c
Rollup merge of #159740 - RalfJung:miri-dedup-exported-symbols, r=bjorn3
jhpratt Jul 24, 2026
da9f1e4
Rollup merge of #159780 - folkertdev:extern-custom-check-fn-ptrs, r=W…
jhpratt Jul 24, 2026
7aaa2d1
Rollup merge of #159786 - AayushMainali-Github:fix-142648-ignore-hidd…
jhpratt Jul 24, 2026
007da6a
Rollup merge of #159819 - Vastargazing:fix/poison-error-auto-cfg-note…
jhpratt Jul 24, 2026
8ae7b3a
Rollup merge of #155388 - lcnr:norm-where-bounds-may-be-productive, r…
jhpratt Jul 24, 2026
61cb79d
Rollup merge of #155914 - lcnr:search-graph-bail-on-ambig, r=BoxyUwU
jhpratt Jul 24, 2026
822b99b
Rollup merge of #159411 - GuillaumeGomez:show-coverage, r=Urgau,aDotI…
jhpratt Jul 24, 2026
759dbe4
Rollup merge of #159439 - PaulDance:patches/fix-win7-dir-remove-file,…
jhpratt Jul 24, 2026
12e7ed0
Rollup merge of #159809 - nnethercote:fix-target_features-messages, r…
jhpratt Jul 24, 2026
cf69066
Rollup merge of #159826 - mejrs:sugar_parens, r=JonathanBrouwer
jhpratt Jul 24, 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
1 change: 1 addition & 0 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4509,6 +4509,7 @@ dependencies = [
"rustc_middle",
"rustc_session",
"rustc_span",
"rustc_symbol_mangling",
"rustc_target",
"serde",
"serde_json",
Expand Down
78 changes: 57 additions & 21 deletions compiler/rustc_ast/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2339,27 +2339,7 @@ pub struct FnSig {
impl FnSig {
/// Return a span encompassing the header, or where to insert it if empty.
pub fn header_span(&self) -> Span {
match self.header.ext {
Extern::Implicit(span) | Extern::Explicit(_, span) => {
return self.span.with_hi(span.hi());
}
Extern::None => {}
}

match self.header.safety {
Safety::Unsafe(span) | Safety::Safe(span) => return self.span.with_hi(span.hi()),
Safety::Default => {}
};

if let Some(coroutine_kind) = self.header.coroutine_kind {
return self.span.with_hi(coroutine_kind.span().hi());
}

if let Const::Yes(span) = self.header.constness {
return self.span.with_hi(span.hi());
}

self.span.shrink_to_lo()
self.header.span().unwrap_or(self.span.shrink_to_lo())
}

/// The span of the header's safety, or where to insert it if empty.
Expand All @@ -2382,6 +2362,19 @@ impl FnSig {
pub fn extern_span(&self) -> Span {
self.header.ext.span().unwrap_or(self.safety_span().shrink_to_hi())
}

pub fn as_borrowed(&self) -> BorrowedFnSig<'_> {
BorrowedFnSig { header: self.header, decl: &self.decl, span: self.span }
}
}

/// A borrowed version of `FnSig`, used to share logic between function declarations and function
/// pointer types.
#[derive(Clone, Debug)]
pub struct BorrowedFnSig<'a> {
pub header: FnHeader,
pub decl: &'a FnDecl,
pub span: Span,
}

/// A constraint on an associated item.
Expand Down Expand Up @@ -2487,6 +2480,16 @@ pub struct FnPtrTy {
pub decl_span: Span,
}

impl FnPtrTy {
pub fn header(&self) -> FnHeader {
FnHeader { constness: Const::No, coroutine_kind: None, safety: self.safety, ext: self.ext }
}

pub fn as_borrowed_fn_sig<'a>(&'a self) -> BorrowedFnSig<'a> {
BorrowedFnSig { header: self.header(), decl: &self.decl, span: self.decl_span }
}
}

#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
pub struct UnsafeBinderTy {
pub generic_params: ThinVec<GenericParam>,
Expand Down Expand Up @@ -3402,6 +3405,15 @@ pub enum AttrStyle {
Inner,
}

impl AttrStyle {
pub fn line_doc_comment_prefix(self) -> &'static str {
match self {
AttrStyle::Outer => "///",
AttrStyle::Inner => "//!",
}
}
}

/// A list of attributes.
pub type AttrVec = ThinVec<Attribute>;

Expand Down Expand Up @@ -3836,6 +3848,30 @@ impl FnHeader {
|| matches!(constness, Const::Yes(_))
|| !matches!(ext, Extern::None)
}

pub fn span(&self) -> Option<Span> {
let mut spans = smallvec::SmallVec::<[Span; 4]>::new();

match self.ext {
Extern::Implicit(span) | Extern::Explicit(_, span) => spans.push(span),
Extern::None => {}
}

match self.safety {
Safety::Unsafe(span) | Safety::Safe(span) => spans.push(span),
Safety::Default => {}
};

if let Some(coroutine_kind) = self.coroutine_kind {
spans.push(coroutine_kind.span());
}

if let Const::Yes(span) = self.constness {
spans.push(span)
}

spans.into_iter().reduce(Span::to)
}
}

impl Default for FnHeader {
Expand Down
108 changes: 81 additions & 27 deletions compiler/rustc_ast_passes/src/ast_validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -546,7 +546,13 @@ impl<'a> AstValidator<'a> {
}

/// Check that the signature of this function does not violate the constraints of its ABI.
fn check_extern_fn_signature(&self, abi: ExternAbi, ctxt: FnCtxt, ident: &Ident, sig: &FnSig) {
fn check_extern_fn_signature(
&self,
abi: ExternAbi,
ctxt: FnCtxt,
opt_function_name: Option<&Ident>, // None for function pointers
sig: &BorrowedFnSig<'_>,
) {
match AbiMap::from_target(&self.sess.target).canonize_abi(abi, false) {
AbiMapping::Direct(canon_abi) | AbiMapping::Deprecated(canon_abi) => {
match canon_abi {
Expand All @@ -569,13 +575,13 @@ impl<'a> AstValidator<'a> {

CanonAbi::Custom => {
// An `extern "custom"` function must be unsafe.
self.reject_safe_fn(abi, ctxt, sig);
self.reject_safe_fn(abi, ctxt, sig, opt_function_name.is_none());

// An `extern "custom"` function cannot be `async` and/or `gen`.
self.reject_coroutine(abi, sig);

// An `extern "custom"` function must have type `fn()`.
self.reject_params_or_return(abi, ident, sig);
self.reject_params_or_return(abi, opt_function_name, sig);
}

CanonAbi::Interrupt(interrupt_kind) => {
Expand All @@ -600,7 +606,7 @@ impl<'a> AstValidator<'a> {
self.reject_return(abi, sig);
} else {
// An `extern "interrupt"` function must have type `fn()`.
self.reject_params_or_return(abi, ident, sig);
self.reject_params_or_return(abi, opt_function_name, sig);
}
}
}
Expand All @@ -609,18 +615,27 @@ impl<'a> AstValidator<'a> {
}
}

fn reject_safe_fn(&self, abi: ExternAbi, ctxt: FnCtxt, sig: &FnSig) {
fn reject_safe_fn(
&self,
abi: ExternAbi,
ctxt: FnCtxt,
sig: &BorrowedFnSig<'_>,
is_fn_ptr: bool,
) {
let dcx = self.dcx();

match sig.header.safety {
Safety::Unsafe(_) => { /* all good */ }
Safety::Safe(safe_span) => {
let source_map = self.sess.psess.source_map();
let safe_span = source_map.span_until_non_whitespace(safe_span.to(sig.span));
dcx.emit_err(diagnostics::AbiCustomSafeForeignFunction {
span: sig.span,
safe_span,
});
// Function pointers already error when `safe` is used.
if !is_fn_ptr {
let source_map = self.sess.psess.source_map();
let safe_span = source_map.span_until_non_whitespace(safe_span.to(sig.span));
dcx.emit_err(diagnostics::AbiCustomSafeForeignFunction {
span: sig.span,
safe_span,
});
}
}
Safety::Default => match ctxt {
FnCtxt::Foreign => { /* all good */ }
Expand All @@ -635,7 +650,7 @@ impl<'a> AstValidator<'a> {
}
}

fn reject_coroutine(&self, abi: ExternAbi, sig: &FnSig) {
fn reject_coroutine(&self, abi: ExternAbi, sig: &BorrowedFnSig<'_>) {
if let Some(coroutine_kind) = sig.header.coroutine_kind {
let coroutine_kind_span = self
.sess
Expand All @@ -652,7 +667,7 @@ impl<'a> AstValidator<'a> {
}
}

fn reject_return(&self, abi: ExternAbi, sig: &FnSig) {
fn reject_return(&self, abi: ExternAbi, sig: &BorrowedFnSig<'_>) {
if let FnRetTy::Ty(ref ret_ty) = sig.decl.output
&& match &ret_ty.kind {
TyKind::Never => false,
Expand All @@ -664,29 +679,41 @@ impl<'a> AstValidator<'a> {
}
}

fn reject_params_or_return(&self, abi: ExternAbi, ident: &Ident, sig: &FnSig) {
fn reject_params_or_return(
&self,
abi: ExternAbi,
opt_function_name: Option<&Ident>, // None for function pointers
sig: &BorrowedFnSig<'_>,
) {
let mut spans: Vec<_> = sig.decl.inputs.iter().map(|p| p.span).collect();

let allowed_return = |ret_ty: &Ty| match &ret_ty.kind {
TyKind::Never if abi != ExternAbi::Custom => true,
TyKind::Tup(tup) if tup.is_empty() => true,
_ => false,
};

if let FnRetTy::Ty(ref ret_ty) = sig.decl.output
&& match &ret_ty.kind {
TyKind::Never => false,
TyKind::Tup(tup) if tup.is_empty() => false,
_ => true,
}
&& !allowed_return(ret_ty)
{
spans.push(ret_ty.span);
}

if !spans.is_empty() {
let header_span = sig.header_span();
let header_span = sig.header.span().unwrap_or(sig.span.shrink_to_lo());
let suggestion_span = header_span.shrink_to_hi().to(sig.decl.output.span());
let padding = if header_span.is_empty() { "" } else { " " };

self.dcx().emit_err(diagnostics::AbiMustNotHaveParametersOrReturnType {
spans,
symbol: ident.name,
abi,

suggestion_span,
padding,
abi,
symbol: match opt_function_name {
Some(ident) => format!(" {}", ident.name),
None => String::new(),
},
});
}
}
Expand Down Expand Up @@ -717,8 +744,12 @@ impl<'a> AstValidator<'a> {
}

fn check_fn_ptr_safety(&self, span: Span, safety: Safety) {
if matches!(safety, Safety::Safe(_)) {
self.dcx().emit_err(diagnostics::InvalidSafetyOnFnPtr { span });
if let Safety::Safe(safe_span) = safety {
let remove_span = self.sess.source_map().span_until_non_whitespace(span);
self.dcx().emit_err(diagnostics::InvalidSafetyOnFnPtr {
span: safe_span,
safe_span: remove_span,
});
}
}

Expand Down Expand Up @@ -1138,6 +1169,24 @@ impl<'a> AstValidator<'a> {
if let Extern::Implicit(extern_span) = bfty.ext {
self.handle_missing_abi(extern_span, ty.id);
}

let ext = match bfty.ext {
Extern::None => None,
Extern::Implicit(_) => Some(ExternAbi::FALLBACK),
Extern::Explicit(str_lit, _) => {
ExternAbi::from_str(str_lit.symbol.as_str()).ok()
}
};

// Some ABIs impose special restrictions on the signature.
if let Some(extern_abi) = ext {
self.check_extern_fn_signature(
extern_abi,
FnCtxt::Free,
None,
&bfty.as_borrowed_fn_sig(),
);
}
}
TyKind::TraitObject(bounds, ..) => {
let mut any_lifetime_bounds = false;
Expand Down Expand Up @@ -1664,8 +1713,8 @@ impl Visitor<'_> for AstValidator<'_> {
self.check_extern_fn_signature(
self.extern_mod_abi.unwrap_or(ExternAbi::FALLBACK),
FnCtxt::Foreign,
ident,
sig,
Some(ident),
&sig.as_borrowed(),
);

if let Some(attr) = attr::find_by_name(fi.attrs(), sym::track_caller)
Expand Down Expand Up @@ -1870,7 +1919,12 @@ impl Visitor<'_> for AstValidator<'_> {

if let Some((extern_abi, extern_abi_span)) = ext {
// Some ABIs impose special restrictions on the signature.
self.check_extern_fn_signature(extern_abi, ctxt, &fun.ident, &fun.sig);
self.check_extern_fn_signature(
extern_abi,
ctxt,
Some(&fun.ident),
&fun.sig.as_borrowed(),
);

// #[track_caller] can only be used with the rust ABI.
if let Some(attr) = attr::find_by_name(attrs, sym::track_caller)
Expand Down
11 changes: 9 additions & 2 deletions compiler/rustc_ast_passes/src/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -382,6 +382,13 @@ pub(crate) struct InvalidSafetyOnItem {
pub(crate) struct InvalidSafetyOnFnPtr {
#[primary_span]
pub span: Span,
#[suggestion(
"remove the `safe` qualifier",
code = "",
applicability = "machine-applicable",
style = "verbose"
)]
pub safe_span: Span,
}

#[derive(Diagnostic)]
Expand Down Expand Up @@ -1115,11 +1122,11 @@ pub(crate) struct AbiMustNotHaveParametersOrReturnType {
#[suggestion(
"remove the parameters and return type",
applicability = "maybe-incorrect",
code = "{padding}fn {symbol}()",
code = "{padding}fn{symbol}()",
style = "verbose"
)]
pub suggestion_span: Span,
pub symbol: Symbol,
pub symbol: String,
pub padding: &'static str,
}

Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_attr_parsing/src/attributes/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ pub(crate) struct RustcParenSugarParser;
impl NoArgsAttributeParser for RustcParenSugarParser {
const PATH: &[Symbol] = &[sym::rustc_paren_sugar];
const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Trait)]);
const STABILITY: AttributeStability = unstable!(rustc_attrs);
const STABILITY: AttributeStability = unstable!(unboxed_closures);
const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcParenSugar;
}

Expand Down
Loading
Loading