Skip to content

Rollup of 11 pull requests #145475

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

Merged
merged 25 commits into from
Aug 16, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
87dd469
Add `Default` impls for `Pin`ned `Box`, `Rc`, `Arc`
Jules-Bertholet Jul 15, 2025
14c6e50
Stabilize as_array_of_cells
jsimmons Jul 17, 2025
b038197
Stabilize `core::iter::chain`
rossmacarthur Aug 5, 2025
2218ff1
fix: Reject async assoc fns of const traits/impls in ast_passes
ShoyuVanilla Aug 4, 2025
f39085b
Add `derive_from` unstable feature
Kobzol Aug 4, 2025
e935a15
Create unstable `From` builtin macro and register it
Kobzol Aug 4, 2025
c0839ea
Add feature gate test
Kobzol Aug 4, 2025
1f3a747
Implement `#[derive(From)]`
Kobzol Aug 15, 2025
f36ab49
fix(tests/rmake/wasm-unexpected-features): change features from `WASM…
StackOverflowExcept1on Aug 15, 2025
33218a2
Remove duplicated tracing span in bootstrap
Kobzol Aug 15, 2025
e9ce9ff
Fix tracing debug representation of steps without arguments in bootstrap
Kobzol Aug 15, 2025
24f5cc4
Do not copy files in `copy_src_dirs` in dry run
Kobzol Aug 15, 2025
5ee2224
stabilize const exposed provenance
Kivooeo Aug 15, 2025
cd37ed5
Enable new `[range-diff]` feature in triagebot
Urgau Aug 15, 2025
41e40f3
Rollup merge of #143717 - Jules-Bertholet:pin-default, r=dtolnay
jhpratt Aug 15, 2025
7a05f26
Rollup merge of #144054 - jsimmons:stabilize-as-array-of-cells, r=tgr…
jhpratt Aug 15, 2025
d077146
Rollup merge of #144907 - ShoyuVanilla:no-const-async, r=fmease
jhpratt Aug 15, 2025
2b1a288
Rollup merge of #144922 - Kobzol:derive-from, r=nnethercote
jhpratt Aug 15, 2025
2776a21
Rollup merge of #144963 - rossmacarthur-forks:stabilize-core-iter-cha…
jhpratt Aug 15, 2025
58c08c5
Rollup merge of #145436 - StackOverflowExcept1on:patch-1, r=alexcrichton
jhpratt Aug 15, 2025
71adb87
Rollup merge of #145453 - Kobzol:bootstrap-cmd-span, r=jieyouxu
jhpratt Aug 15, 2025
4fa90ef
Rollup merge of #145454 - Kobzol:bootstrap-fix-step-debug-repr, r=jie…
jhpratt Aug 15, 2025
56e9a67
Rollup merge of #145455 - Kobzol:bootstrap-copy-src-dirs-dry-run, r=j…
jhpratt Aug 15, 2025
2a9bb56
Rollup merge of #145462 - Kivooeo:stabilize-const_exposed_provenance,…
jhpratt Aug 15, 2025
cf28e2b
Rollup merge of #145466 - Urgau:triagebot-range-diff, r=Kobzol
jhpratt Aug 15, 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
7 changes: 7 additions & 0 deletions compiler/rustc_ast_passes/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,13 @@ ast_passes_assoc_type_without_body =
associated type in `impl` without body
.suggestion = provide a definition for the type
ast_passes_async_fn_in_const_trait_or_trait_impl =
async functions are not allowed in `const` {$in_impl ->
[true] trait impls
*[false] traits
}
.label = associated functions of `const` cannot be declared `async`
ast_passes_at_least_one_trait = at least one trait must be specified
ast_passes_auto_generic = auto traits cannot have generic parameters
Expand Down
16 changes: 16 additions & 0 deletions compiler/rustc_ast_passes/src/ast_validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,21 @@ impl<'a> AstValidator<'a> {
});
}

fn check_async_fn_in_const_trait_or_impl(&self, sig: &FnSig, parent: &TraitOrTraitImpl) {
let Some(const_keyword) = parent.constness() else { return };

let Some(CoroutineKind::Async { span: async_keyword, .. }) = sig.header.coroutine_kind
else {
return;
};

self.dcx().emit_err(errors::AsyncFnInConstTraitOrTraitImpl {
async_keyword,
in_impl: matches!(parent, TraitOrTraitImpl::TraitImpl { .. }),
const_keyword,
});
}

fn check_fn_decl(&self, fn_decl: &FnDecl, self_semantic: SelfSemantic) {
self.check_decl_num_args(fn_decl);
self.check_decl_cvariadic_pos(fn_decl);
Expand Down Expand Up @@ -1578,6 +1593,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
self.visibility_not_permitted(&item.vis, errors::VisibilityNotPermittedNote::TraitImpl);
if let AssocItemKind::Fn(box Fn { sig, .. }) = &item.kind {
self.check_trait_fn_not_const(sig.header.constness, parent);
self.check_async_fn_in_const_trait_or_impl(sig, parent);
}
}

Expand Down
10 changes: 10 additions & 0 deletions compiler/rustc_ast_passes/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,16 @@ pub(crate) struct TraitFnConst {
pub make_trait_const_sugg: Option<Span>,
}

#[derive(Diagnostic)]
#[diag(ast_passes_async_fn_in_const_trait_or_trait_impl)]
pub(crate) struct AsyncFnInConstTraitOrTraitImpl {
#[primary_span]
pub async_keyword: Span,
pub in_impl: bool,
#[label]
pub const_keyword: Span,
}

#[derive(Diagnostic)]
#[diag(ast_passes_forbidden_bound)]
pub(crate) struct ForbiddenBound {
Expand Down
9 changes: 9 additions & 0 deletions compiler/rustc_builtin_macros/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,15 @@ builtin_macros_format_unused_args = multiple unused formatting arguments

builtin_macros_format_use_positional = consider using a positional formatting argument instead

builtin_macros_derive_from_wrong_target = `#[derive(From)]` used on {$kind}

builtin_macros_derive_from_wrong_field_count = `#[derive(From)]` used on a struct with {$multiple_fields ->
[true] multiple fields
*[false] no fields
}

builtin_macros_derive_from_usage_note = `#[derive(From)]` can only be used on structs with exactly one field

builtin_macros_multiple_default_attrs = multiple `#[default]` attributes
.note = only one `#[default]` attribute is needed
.label = `#[default]` used here
Expand Down
132 changes: 132 additions & 0 deletions compiler/rustc_builtin_macros/src/deriving/from.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
use rustc_ast as ast;
use rustc_ast::{ItemKind, VariantData};
use rustc_errors::MultiSpan;
use rustc_expand::base::{Annotatable, DummyResult, ExtCtxt};
use rustc_span::{Ident, Span, kw, sym};
use thin_vec::thin_vec;

use crate::deriving::generic::ty::{Bounds, Path, PathKind, Ty};
use crate::deriving::generic::{
BlockOrExpr, FieldlessVariantsStrategy, MethodDef, SubstructureFields, TraitDef,
combine_substructure,
};
use crate::deriving::pathvec_std;
use crate::errors;

/// Generate an implementation of the `From` trait, provided that `item`
/// is a struct or a tuple struct with exactly one field.
pub(crate) fn expand_deriving_from(
cx: &ExtCtxt<'_>,
span: Span,
mitem: &ast::MetaItem,
annotatable: &Annotatable,
push: &mut dyn FnMut(Annotatable),
is_const: bool,
) {
let Annotatable::Item(item) = &annotatable else {
cx.dcx().bug("derive(From) used on something else than an item");
};

// #[derive(From)] is currently usable only on structs with exactly one field.
let field = if let ItemKind::Struct(_, _, data) = &item.kind
&& let [field] = data.fields()
{
Some(field.clone())
} else {
None
};

let from_type = match &field {
Some(field) => Ty::AstTy(field.ty.clone()),
// We don't have a type to put into From<...> if we don't have a single field, so just put
// unit there.
None => Ty::Unit,
};
let path =
Path::new_(pathvec_std!(convert::From), vec![Box::new(from_type.clone())], PathKind::Std);

// Generate code like this:
//
// struct S(u32);
// #[automatically_derived]
// impl ::core::convert::From<u32> for S {
// #[inline]
// fn from(value: u32) -> S {
// Self(value)
// }
// }
let from_trait_def = TraitDef {
span,
path,
skip_path_as_bound: true,
needs_copy_as_bound_if_packed: false,
additional_bounds: Vec::new(),
supports_unions: false,
methods: vec![MethodDef {
name: sym::from,
generics: Bounds { bounds: vec![] },
explicit_self: false,
nonself_args: vec![(from_type, sym::value)],
ret_ty: Ty::Self_,
attributes: thin_vec![cx.attr_word(sym::inline, span)],
fieldless_variants_strategy: FieldlessVariantsStrategy::Default,
combine_substructure: combine_substructure(Box::new(|cx, span, substructure| {
let Some(field) = &field else {
let item_span = item.kind.ident().map(|ident| ident.span).unwrap_or(item.span);
let err_span = MultiSpan::from_spans(vec![span, item_span]);
let error = match &item.kind {
ItemKind::Struct(_, _, data) => {
cx.dcx().emit_err(errors::DeriveFromWrongFieldCount {
span: err_span,
multiple_fields: data.fields().len() > 1,
})
}
ItemKind::Enum(_, _, _) | ItemKind::Union(_, _, _) => {
cx.dcx().emit_err(errors::DeriveFromWrongTarget {
span: err_span,
kind: &format!("{} {}", item.kind.article(), item.kind.descr()),
})
}
_ => cx.dcx().bug("Invalid derive(From) ADT input"),
};

return BlockOrExpr::new_expr(DummyResult::raw_expr(span, Some(error)));
};

let self_kw = Ident::new(kw::SelfUpper, span);
let expr: Box<ast::Expr> = match substructure.fields {
SubstructureFields::StaticStruct(variant, _) => match variant {
// Self {
// field: value
// }
VariantData::Struct { .. } => cx.expr_struct_ident(
span,
self_kw,
thin_vec![cx.field_imm(
span,
field.ident.unwrap(),
cx.expr_ident(span, Ident::new(sym::value, span))
)],
),
// Self(value)
VariantData::Tuple(_, _) => cx.expr_call_ident(
span,
self_kw,
thin_vec![cx.expr_ident(span, Ident::new(sym::value, span))],
),
variant => {
cx.dcx().bug(format!("Invalid derive(From) ADT variant: {variant:?}"));
}
},
_ => cx.dcx().bug("Invalid derive(From) ADT input"),
};
BlockOrExpr::new_expr(expr)
})),
}],
associated_types: Vec::new(),
is_const,
is_staged_api_crate: cx.ecfg.features.staged_api(),
};

from_trait_def.expand(cx, mitem, annotatable, push);
}
11 changes: 9 additions & 2 deletions compiler/rustc_builtin_macros/src/deriving/generic/ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
//! when specifying impls to be derived.

pub(crate) use Ty::*;
use rustc_ast::{self as ast, Expr, GenericArg, GenericParamKind, Generics, SelfKind};
use rustc_ast::{self as ast, Expr, GenericArg, GenericParamKind, Generics, SelfKind, TyKind};
use rustc_expand::base::ExtCtxt;
use rustc_span::source_map::respan;
use rustc_span::{DUMMY_SP, Ident, Span, Symbol, kw};
Expand Down Expand Up @@ -65,7 +65,7 @@ impl Path {
}
}

/// A type. Supports pointers, Self, and literals.
/// A type. Supports pointers, Self, literals, unit or an arbitrary AST path.
#[derive(Clone)]
pub(crate) enum Ty {
Self_,
Expand All @@ -76,6 +76,8 @@ pub(crate) enum Ty {
Path(Path),
/// For () return types.
Unit,
/// An arbitrary type.
AstTy(Box<ast::Ty>),
}

pub(crate) fn self_ref() -> Ty {
Expand All @@ -101,6 +103,7 @@ impl Ty {
let ty = ast::TyKind::Tup(ThinVec::new());
cx.ty(span, ty)
}
AstTy(ty) => ty.clone(),
}
}

Expand Down Expand Up @@ -132,6 +135,10 @@ impl Ty {
cx.path_all(span, false, vec![self_ty], params)
}
Path(p) => p.to_path(cx, span, self_ty, generics),
AstTy(ty) => match &ty.kind {
TyKind::Path(_, path) => path.clone(),
_ => cx.dcx().span_bug(span, "non-path in a path in generic `derive`"),
},
Ref(..) => cx.dcx().span_bug(span, "ref in a path in generic `derive`"),
Unit => cx.dcx().span_bug(span, "unit in a path in generic `derive`"),
}
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_builtin_macros/src/deriving/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ pub(crate) mod clone;
pub(crate) mod coerce_pointee;
pub(crate) mod debug;
pub(crate) mod default;
pub(crate) mod from;
pub(crate) mod hash;

#[path = "cmp/eq.rs"]
Expand Down
18 changes: 18 additions & 0 deletions compiler/rustc_builtin_macros/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -446,6 +446,24 @@ pub(crate) struct DefaultHasArg {
pub(crate) span: Span,
}

#[derive(Diagnostic)]
#[diag(builtin_macros_derive_from_wrong_target)]
#[note(builtin_macros_derive_from_usage_note)]
pub(crate) struct DeriveFromWrongTarget<'a> {
#[primary_span]
pub(crate) span: MultiSpan,
pub(crate) kind: &'a str,
}

#[derive(Diagnostic)]
#[diag(builtin_macros_derive_from_wrong_field_count)]
#[note(builtin_macros_derive_from_usage_note)]
pub(crate) struct DeriveFromWrongFieldCount {
#[primary_span]
pub(crate) span: MultiSpan,
pub(crate) multiple_fields: bool,
}

#[derive(Diagnostic)]
#[diag(builtin_macros_derive_macro_call)]
pub(crate) struct DeriveMacroCall {
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_builtin_macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand) {
PartialEq: partial_eq::expand_deriving_partial_eq,
PartialOrd: partial_ord::expand_deriving_partial_ord,
CoercePointee: coerce_pointee::expand_deriving_coerce_pointee,
From: from::expand_deriving_from,
}

let client = rustc_proc_macro::bridge::client::Client::expand1(rustc_proc_macro::quote);
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 @@ -470,6 +470,8 @@ declare_features! (
(unstable, deprecated_suggestion, "1.61.0", Some(94785)),
/// Allows deref patterns.
(incomplete, deref_patterns, "1.79.0", Some(87121)),
/// Allows deriving the From trait on single-field structs.
(unstable, derive_from, "CURRENT_RUSTC_VERSION", Some(144889)),
/// Tells rustdoc to automatically generate `#[doc(cfg(...))]`.
(unstable, doc_auto_cfg, "1.58.0", Some(43781)),
/// Allows `#[doc(cfg(...))]`.
Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -392,6 +392,7 @@ symbols! {
__D,
__H,
__S,
__T,
__awaitee,
__try_var,
_t,
Expand Down Expand Up @@ -746,6 +747,7 @@ symbols! {
contracts_ensures,
contracts_internals,
contracts_requires,
convert,
convert_identity,
copy,
copy_closures,
Expand Down Expand Up @@ -847,6 +849,7 @@ symbols! {
derive_const,
derive_const_issue: "118304",
derive_default_enum,
derive_from,
derive_smart_pointer,
destruct,
destructuring_assignment,
Expand Down Expand Up @@ -2331,6 +2334,7 @@ symbols! {
va_start,
val,
validity,
value,
values,
var,
variant_count,
Expand Down
16 changes: 15 additions & 1 deletion library/alloc/src/boxed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1672,7 +1672,7 @@ unsafe impl<#[may_dangle] T: ?Sized, A: Allocator> Drop for Box<T, A> {
#[cfg(not(no_global_oom_handling))]
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: Default> Default for Box<T> {
/// Creates a `Box<T>`, with the `Default` value for T.
/// Creates a `Box<T>`, with the `Default` value for `T`.
#[inline]
fn default() -> Self {
let mut x: Box<mem::MaybeUninit<T>> = Box::new_uninit();
Expand All @@ -1695,6 +1695,7 @@ impl<T: Default> Default for Box<T> {
#[cfg(not(no_global_oom_handling))]
#[stable(feature = "rust1", since = "1.0.0")]
impl<T> Default for Box<[T]> {
/// Creates an empty `[T]` inside a `Box`.
#[inline]
fn default() -> Self {
let ptr: Unique<[T]> = Unique::<[T; 0]>::dangling();
Expand All @@ -1716,6 +1717,19 @@ impl Default for Box<str> {
}
}

#[cfg(not(no_global_oom_handling))]
#[stable(feature = "pin_default_impls", since = "CURRENT_RUSTC_VERSION")]
impl<T> Default for Pin<Box<T>>
where
T: ?Sized,
Box<T>: Default,
{
#[inline]
fn default() -> Self {
Box::into_pin(Box::<T>::default())
}
}

#[cfg(not(no_global_oom_handling))]
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: Clone, A: Allocator + Clone> Clone for Box<T, A> {
Expand Down
Loading
Loading