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
033711c
Stabilize `const_mul_add`
tgross35 Oct 23, 2025
93cd4f8
link funding page in `.github/FUNDING.yml`
WaffleLapkin Nov 27, 2025
5c91f2c
Make `--print=backend-has-zstd` work by default on any backend
Zalathar Dec 8, 2025
4033d19
Experimentally add *heterogeneous* `try` blocks
scottmcm Nov 30, 2025
f9e1031
Update clippy for the ast `TryBlock` change
scottmcm Nov 30, 2025
35598c1
Also get rustfmt to at least compile
scottmcm Nov 30, 2025
a3970b0
Build auxiliary in pretty tests
aerooneqq Dec 10, 2025
9e4e9e4
Use `PointeeSized` bound for `TrivialClone` impls
theemathas Dec 10, 2025
0eed5ab
introduce fcw macro
jdonszelmann Dec 10, 2025
1eabe65
adapt formatting to use new fcw info structure
jdonszelmann Dec 10, 2025
1ef1ec1
bless the tests
jdonszelmann Dec 10, 2025
183048c
update docs
jdonszelmann Dec 10, 2025
26ae475
Rollup merge of #148052 - tgross35:stabilize-const_mul_add, r=RalfJung
matthiaskrgr Dec 10, 2025
54195b9
Rollup merge of #149386 - WaffleLapkin:display-funding, r=Kobzol
matthiaskrgr Dec 10, 2025
02a58a9
Rollup merge of #149489 - scottmcm:try-bikeshed, r=nnethercote
matthiaskrgr Dec 10, 2025
d1e921e
Rollup merge of #149764 - Zalathar:has-zstd, r=bjorn3
matthiaskrgr Dec 10, 2025
7b2f36e
Rollup merge of #149838 - aerooneqq:build-aux-in-pp-tests, r=petroche…
matthiaskrgr Dec 10, 2025
03028df
Rollup merge of #149839 - theemathas:trivial-clone-pointee-sized, r=j…
matthiaskrgr Dec 10, 2025
eab1036
Rollup merge of #149846 - jdonszelmann:links-for-all-fcws, r=wafflela…
matthiaskrgr Dec 10, 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 .github/FUNDING.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
custom: ["rust-lang.org/funding"]
10 changes: 8 additions & 2 deletions compiler/rustc_ast/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1819,8 +1819,14 @@ pub enum ExprKind {
/// A use expression (`x.use`). Span is of use keyword.
Use(Box<Expr>, Span),

/// A try block (`try { ... }`).
TryBlock(Box<Block>),
/// A try block (`try { ... }`), if the type is `None`, or
/// A try block (`try bikeshed Ty { ... }`) if the type is `Some`.
///
/// Note that `try bikeshed` is a *deliberately ridiculous* placeholder
/// syntax to avoid deciding what keyword or symbol should go there.
/// It's that way for experimentation only; an RFC to decide the final
/// semantics and syntax would be needed to put it on stabilization-track.
TryBlock(Box<Block>, Option<Box<Ty>>),

/// An assignment (`a = foo()`).
/// The `Span` argument is the span of the `=` token.
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_ast/src/visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1048,8 +1048,8 @@ macro_rules! common_visitor_and_walkers {
visit_visitable!($($mut)? vis, kind),
ExprKind::Try(subexpression) =>
visit_visitable!($($mut)? vis, subexpression),
ExprKind::TryBlock(body) =>
visit_visitable!($($mut)? vis, body),
ExprKind::TryBlock(body, optional_type) =>
visit_visitable!($($mut)? vis, body, optional_type),
ExprKind::Lit(token) =>
visit_visitable!($($mut)? vis, token),
ExprKind::IncludedBytes(bytes) =>
Expand Down
74 changes: 53 additions & 21 deletions compiler/rustc_ast_lowering/src/expr.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use std::mem;
use std::ops::ControlFlow;
use std::sync::Arc;

Expand Down Expand Up @@ -27,7 +28,9 @@ use super::{
GenericArgsMode, ImplTraitContext, LoweringContext, ParamMode, ResolverAstLoweringExt,
};
use crate::errors::{InvalidLegacyConstGenericArg, UseConstGenericArg, YieldInClosure};
use crate::{AllowReturnTypeNotation, FnDeclKind, ImplTraitPosition, fluent_generated};
use crate::{
AllowReturnTypeNotation, FnDeclKind, ImplTraitPosition, TryBlockScope, fluent_generated,
};

struct WillCreateDefIdsVisitor {}

Expand Down Expand Up @@ -199,7 +202,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
)
})
}
ExprKind::TryBlock(body) => self.lower_expr_try_block(body),
ExprKind::TryBlock(body, opt_ty) => {
self.lower_expr_try_block(body, opt_ty.as_deref())
}
ExprKind::Match(expr, arms, kind) => hir::ExprKind::Match(
self.lower_expr(expr),
self.arena.alloc_from_iter(arms.iter().map(|x| self.lower_arm(x))),
Expand Down Expand Up @@ -562,9 +567,14 @@ impl<'hir> LoweringContext<'_, 'hir> {
/// Desugar `try { <stmts>; <expr> }` into `{ <stmts>; ::std::ops::Try::from_output(<expr>) }`,
/// `try { <stmts>; }` into `{ <stmts>; ::std::ops::Try::from_output(()) }`
/// and save the block id to use it as a break target for desugaring of the `?` operator.
fn lower_expr_try_block(&mut self, body: &Block) -> hir::ExprKind<'hir> {
fn lower_expr_try_block(&mut self, body: &Block, opt_ty: Option<&Ty>) -> hir::ExprKind<'hir> {
let body_hir_id = self.lower_node_id(body.id);
self.with_catch_scope(body_hir_id, |this| {
let new_scope = if opt_ty.is_some() {
TryBlockScope::Heterogeneous(body_hir_id)
} else {
TryBlockScope::Homogeneous(body_hir_id)
};
let whole_block = self.with_try_block_scope(new_scope, |this| {
let mut block = this.lower_block_noalloc(body_hir_id, body, true);

// Final expression of the block (if present) or `()` with span at the end of block
Expand Down Expand Up @@ -598,8 +608,16 @@ impl<'hir> LoweringContext<'_, 'hir> {
ok_wrapped_span,
));

hir::ExprKind::Block(this.arena.alloc(block), None)
})
this.arena.alloc(block)
});

if let Some(ty) = opt_ty {
let ty = self.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::Path));
let block_expr = self.arena.alloc(self.expr_block(whole_block));
hir::ExprKind::Type(block_expr, ty)
} else {
hir::ExprKind::Block(whole_block, None)
}
}

fn wrap_in_try_constructor(
Expand Down Expand Up @@ -1617,10 +1635,14 @@ impl<'hir> LoweringContext<'_, 'hir> {
}
}

fn with_catch_scope<T>(&mut self, catch_id: hir::HirId, f: impl FnOnce(&mut Self) -> T) -> T {
let old_scope = self.catch_scope.replace(catch_id);
fn with_try_block_scope<T>(
&mut self,
scope: TryBlockScope,
f: impl FnOnce(&mut Self) -> T,
) -> T {
let old_scope = mem::replace(&mut self.try_block_scope, scope);
let result = f(self);
self.catch_scope = old_scope;
self.try_block_scope = old_scope;
result
}

Expand Down Expand Up @@ -1978,18 +2000,25 @@ impl<'hir> LoweringContext<'_, 'hir> {
let residual_ident = Ident::with_dummy_span(sym::residual);
let (residual_local, residual_local_nid) = self.pat_ident(try_span, residual_ident);
let residual_expr = self.expr_ident_mut(try_span, residual_ident, residual_local_nid);

let (constructor_item, target_id) = match self.try_block_scope {
TryBlockScope::Function => {
(hir::LangItem::TryTraitFromResidual, Err(hir::LoopIdError::OutsideLoopScope))
}
TryBlockScope::Homogeneous(block_id) => {
(hir::LangItem::ResidualIntoTryType, Ok(block_id))
}
TryBlockScope::Heterogeneous(block_id) => {
(hir::LangItem::TryTraitFromResidual, Ok(block_id))
}
};
let from_residual_expr = self.wrap_in_try_constructor(
if self.catch_scope.is_some() {
hir::LangItem::ResidualIntoTryType
} else {
hir::LangItem::TryTraitFromResidual
},
constructor_item,
try_span,
self.arena.alloc(residual_expr),
unstable_span,
);
let ret_expr = if let Some(catch_id) = self.catch_scope {
let target_id = Ok(catch_id);
let ret_expr = if target_id.is_ok() {
self.arena.alloc(self.expr(
try_span,
hir::ExprKind::Break(
Expand Down Expand Up @@ -2044,11 +2073,14 @@ impl<'hir> LoweringContext<'_, 'hir> {
yeeted_span,
);

if let Some(catch_id) = self.catch_scope {
let target_id = Ok(catch_id);
hir::ExprKind::Break(hir::Destination { label: None, target_id }, Some(from_yeet_expr))
} else {
self.checked_return(Some(from_yeet_expr))
match self.try_block_scope {
TryBlockScope::Homogeneous(block_id) | TryBlockScope::Heterogeneous(block_id) => {
hir::ExprKind::Break(
hir::Destination { label: None, target_id: Ok(block_id) },
Some(from_yeet_expr),
)
}
TryBlockScope::Function => self.checked_return(Some(from_yeet_expr)),
}
}

Expand Down
21 changes: 17 additions & 4 deletions compiler/rustc_ast_lowering/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
#![feature(if_let_guard)]
// tidy-alphabetical-end

use std::mem;
use std::sync::Arc;

use rustc_ast::node_id::NodeMap;
Expand Down Expand Up @@ -117,7 +118,7 @@ struct LoweringContext<'a, 'hir> {
/// outside of an `async fn`.
current_item: Option<Span>,

catch_scope: Option<HirId>,
try_block_scope: TryBlockScope,
loop_scope: Option<HirId>,
is_in_loop_condition: bool,
is_in_dyn_type: bool,
Expand Down Expand Up @@ -173,7 +174,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
trait_map: Default::default(),

// Lowering state.
catch_scope: None,
try_block_scope: TryBlockScope::Function,
loop_scope: None,
is_in_loop_condition: false,
is_in_dyn_type: false,
Expand Down Expand Up @@ -416,6 +417,18 @@ enum AstOwner<'a> {
ForeignItem(&'a ast::ForeignItem),
}

#[derive(Copy, Clone, Debug)]
enum TryBlockScope {
/// There isn't a `try` block, so a `?` will use `return`.
Function,
/// We're inside a `try { … }` block, so a `?` will block-break
/// from that block using a type depending only on the argument.
Homogeneous(HirId),
/// We're inside a `try as _ { … }` block, so a `?` will block-break
/// from that block using the type specified.
Heterogeneous(HirId),
}

fn index_crate<'a>(
node_id_to_def_id: &NodeMap<LocalDefId>,
krate: &'a Crate,
Expand Down Expand Up @@ -936,10 +949,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {

let old_contract = self.contract_ensures.take();

let catch_scope = self.catch_scope.take();
let try_block_scope = mem::replace(&mut self.try_block_scope, TryBlockScope::Function);
let loop_scope = self.loop_scope.take();
let ret = f(self);
self.catch_scope = catch_scope;
self.try_block_scope = try_block_scope;
self.loop_scope = loop_scope;

self.contract_ensures = old_contract;
Expand Down
10 changes: 9 additions & 1 deletion compiler/rustc_ast_passes/src/feature_gate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -334,9 +334,17 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {

fn visit_expr(&mut self, e: &'a ast::Expr) {
match e.kind {
ast::ExprKind::TryBlock(_) => {
ast::ExprKind::TryBlock(_, None) => {
gate!(&self, try_blocks, e.span, "`try` expression is experimental");
}
ast::ExprKind::TryBlock(_, Some(_)) => {
gate!(
&self,
try_blocks_heterogeneous,
e.span,
"`try bikeshed` expression is experimental"
);
}
ast::ExprKind::Lit(token::Lit {
kind: token::LitKind::Float | token::LitKind::Integer,
suffix,
Expand Down
7 changes: 6 additions & 1 deletion compiler/rustc_ast_pretty/src/pprust/state/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -818,10 +818,15 @@ impl<'a> State<'a> {
);
self.word("?")
}
ast::ExprKind::TryBlock(blk) => {
ast::ExprKind::TryBlock(blk, opt_ty) => {
let cb = self.cbox(0);
let ib = self.ibox(0);
self.word_nbsp("try");
if let Some(ty) = opt_ty {
self.word_nbsp("bikeshed");
self.print_type(ty);
self.space();
}
self.print_block_with_attrs(blk, attrs, cb, ib)
}
ast::ExprKind::UnsafeBinderCast(kind, expr, ty) => {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_builtin_macros/src/assert/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,7 @@ impl<'cx, 'a> Context<'cx, 'a> {
| ExprKind::Path(_, _)
| ExprKind::Ret(_)
| ExprKind::Try(_)
| ExprKind::TryBlock(_)
| ExprKind::TryBlock(_, _)
| ExprKind::Type(_, _)
| ExprKind::Underscore
| ExprKind::While(_, _, _)
Expand Down
12 changes: 1 addition & 11 deletions compiler/rustc_codegen_cranelift/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ use rustc_codegen_ssa::{CodegenResults, TargetConfig};
use rustc_log::tracing::info;
use rustc_middle::dep_graph::{WorkProduct, WorkProductId};
use rustc_session::Session;
use rustc_session::config::{OutputFilenames, PrintKind, PrintRequest};
use rustc_session::config::OutputFilenames;
use rustc_span::{Symbol, sym};
use rustc_target::spec::{Abi, Arch, Env, Os};

Expand Down Expand Up @@ -160,16 +160,6 @@ impl CodegenBackend for CraneliftCodegenBackend {
}
}

fn print(&self, req: &PrintRequest, out: &mut String, _sess: &Session) {
match req.kind {
// FIXME have a default impl that returns false
PrintKind::BackendHasZstd => {
out.push_str("false\n");
}
_ => {}
}
}

fn target_config(&self, sess: &Session) -> TargetConfig {
// FIXME return the actually used target features. this is necessary for #[cfg(target_feature)]
let target_features = match sess.target.arch {
Expand Down
8 changes: 4 additions & 4 deletions compiler/rustc_codegen_llvm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -257,10 +257,6 @@ impl CodegenBackend for LlvmCodegenBackend {
}
writeln!(out).unwrap();
}
PrintKind::BackendHasZstd => {
let has_zstd = llvm::LLVMRustLLVMHasZstdCompression();
writeln!(out, "{has_zstd}").unwrap();
}
PrintKind::CodeModels => {
writeln!(out, "Available code models:").unwrap();
for name in &["tiny", "small", "kernel", "medium", "large"] {
Expand Down Expand Up @@ -314,6 +310,10 @@ impl CodegenBackend for LlvmCodegenBackend {
llvm_util::print_version();
}

fn has_zstd(&self) -> bool {
llvm::LLVMRustLLVMHasZstdCompression()
}

fn target_config(&self, sess: &Session) -> TargetConfig {
target_config(sess)
}
Expand Down
8 changes: 8 additions & 0 deletions compiler/rustc_codegen_ssa/src/traits/backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,14 @@ pub trait CodegenBackend {

fn print_version(&self) {}

/// Value printed by `--print=backend-has-zstd`.
///
/// Used by compiletest to determine whether tests involving zstd compression
/// (e.g. `-Zdebuginfo-compression=zstd`) should be executed or skipped.
fn has_zstd(&self) -> bool {
false
}

/// The metadata loader used to load rlib and dylib metadata.
///
/// Alternative codegen backends may want to use different rlib or dylib formats than the
Expand Down
5 changes: 4 additions & 1 deletion compiler/rustc_driver_impl/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -798,8 +798,11 @@ fn print_crate_info(
let calling_conventions = rustc_abi::all_names();
println_info!("{}", calling_conventions.join("\n"));
}
BackendHasZstd => {
let has_zstd: bool = codegen_backend.has_zstd();
println_info!("{has_zstd}");
}
RelocationModels
| BackendHasZstd
| CodeModels
| TlsModels
| TargetCPUs
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_feature/src/unstable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -663,6 +663,8 @@ declare_features! (
(unstable, trivial_bounds, "1.28.0", Some(48214)),
/// Allows using `try {...}` expressions.
(unstable, try_blocks, "1.29.0", Some(31436)),
/// Allows using `try bikeshed TargetType {...}` expressions.
(unstable, try_blocks_heterogeneous, "CURRENT_RUSTC_VERSION", Some(149488)),
/// Allows `impl Trait` to be used inside type aliases (RFC 2515).
(unstable, type_alias_impl_trait, "1.38.0", Some(63063)),
/// Allows creation of instances of a struct by moving fields that have
Expand Down
1 change: 0 additions & 1 deletion compiler/rustc_hir_typeck/src/upvar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1043,7 +1043,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
}
}
lint.note("for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/disjoint-capture-in-closures.html>");

let diagnostic_msg = format!(
"add a dummy let to cause {migrated_variables_concat} to be fully captured"
Expand Down
Loading
Loading