Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
f31860e
Implement clamp_to
Kyuuhachi Dec 16, 2025
1a7439c
Fix `flag_if_supported` in `cc-rs` by configuring an `out_dir`
Kobzol Jun 20, 2026
f832372
Slightly refactor cc code
Kobzol Jun 20, 2026
ae0fb27
Add missing zlib library to `x86_64-gnu-distcheck`
Kobzol Jun 20, 2026
65f0657
Add `compress-debuginfo` option to bootstrap and fix debuginfo compre…
Kobzol Jun 21, 2026
10c2c9d
Enable debuginfo compression by default in dist builds
Kobzol Jun 21, 2026
d3e3e67
give a better error when `getrandom` fails
jyn514 Jun 25, 2026
3886e7f
Mark linux-getrandom-fallback test as needs-unwind
fs-rachel Jun 25, 2026
03d7851
add EarlyBinder<TraitRef>::def_id helper and remove direct calls to i…
Shourya742 Jun 30, 2026
9f7569b
Do not use zlib compression on Windows and macOS
Kobzol Jun 30, 2026
cd642bb
Remove unnecessary `Clone` derives on resolver types
nnethercote Jun 30, 2026
c6f92dc
Add missing `needs_drop` check to `DroplessArena`.
nnethercote Jul 1, 2026
4f436ab
Document `strip_circumfix` behavior on overlapping prefix and suffix.
theemathas Jul 1, 2026
92c10f9
Support simplest output `Self` mapping in delegation
aerooneqq Jul 1, 2026
e33acb5
Rollup merge of #150075 - Kyuuhachi:limit_to, r=joshtriplett,ChrisDenton
JonathanBrouwer Jul 1, 2026
c8893b7
Rollup merge of #158169 - Kobzol:fix-cc-rs-flag-if-supported, r=bjorn3
JonathanBrouwer Jul 1, 2026
ae124ee
Rollup merge of #158397 - aerooneqq:delegation-self-type-mapping, r=p…
JonathanBrouwer Jul 1, 2026
329a3ba
Rollup merge of #158613 - fs-rachel:fix-getrandom-fallback-test, r=jo…
JonathanBrouwer Jul 1, 2026
915f216
Rollup merge of #158620 - Shourya742:2026-06-30-add-early-binder-def-…
JonathanBrouwer Jul 1, 2026
a20f16e
Rollup merge of #158633 - nnethercote:resolver-Clones, r=petrochenkov
JonathanBrouwer Jul 1, 2026
a7b4cbc
Rollup merge of #158634 - nnethercote:add-missing-needs_drop, r=Nadri…
JonathanBrouwer Jul 1, 2026
e761f13
Rollup merge of #158647 - theemathas:circumfix-overlap, r=clarfonthey
JonathanBrouwer Jul 1, 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
14 changes: 14 additions & 0 deletions bootstrap.example.toml
Original file line number Diff line number Diff line change
Expand Up @@ -697,6 +697,13 @@
# FIXME(#61117): Some tests fail when this option is enabled.
#rust.debuginfo-level-tests = 0

# Compress debuginfo of Rust and C/C++ code.
# Valid options:
# - "off" or false: disable compression
# - true: compress debuginfo with the default compression method (currently zlib)
# - "zlib": compress debuginfo with zlib
#rust.compress-debuginfo = "off"

# Should rustc and the standard library be built with split debuginfo? Default
# is platform dependent.
#
Expand Down Expand Up @@ -1019,6 +1026,13 @@
# and enabling it causes issues.
#split-debuginfo = if linux || windows-gnu { off } else if windows-msvc { packed } else if apple { unpacked }

# Compress debuginfo for Rust and C/C++ code of this target.
# Valid options:
# - "off" or false: disable compression
# - true: compress debuginfo with the default compression method (currently zlib)
# - "zlib": compress debuginfo with zlib
#compress-debuginfo = "off"

# Path to the `llvm-config` binary of the installation of a custom LLVM to link
# against. Note that if this is specified we don't compile LLVM at all for this
# target.
Expand Down
6 changes: 4 additions & 2 deletions compiler/rustc_arena/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -542,11 +542,12 @@ impl DroplessArena {

#[inline]
pub fn alloc_from_iter<T, I: IntoIterator<Item = T>>(&self, iter: I) -> &mut [T] {
assert!(!mem::needs_drop::<T>());
assert!(size_of::<T>() != 0);

// Warning: this function is reentrant: `iter` could hold a reference to `&self` and
// allocate additional elements while we're iterating.
let iter = iter.into_iter();
assert!(size_of::<T>() != 0);
assert!(!mem::needs_drop::<T>());

let size_hint = iter.size_hint();

Expand Down Expand Up @@ -577,6 +578,7 @@ impl DroplessArena {
) -> Result<&mut [T], E> {
// Despite the similarity with `alloc_from_iter`, we cannot reuse their fast case, as we
// cannot know the minimum length of the iterator in this case.
assert!(!mem::needs_drop::<T>());
assert!(size_of::<T>() != 0);

// Takes care of reentrancy.
Expand Down
68 changes: 65 additions & 3 deletions compiler/rustc_ast_lowering/src/delegation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ use rustc_middle::span_bug;
use rustc_middle::ty::{Asyncness, PerOwnerResolverData};
use rustc_span::def_id::{DefId, LocalDefId};
use rustc_span::symbol::kw;
use rustc_span::{ErrorGuaranteed, Ident, Span, Symbol};
use rustc_span::{ErrorGuaranteed, Ident, Span, Symbol, sym};

use crate::delegation::generics::{
GenericsGenerationResult, GenericsGenerationResults, GenericsPosition,
Expand Down Expand Up @@ -664,11 +664,34 @@ impl<'hir> LoweringContext<'_, 'hir> {

let callee_path = self.arena.alloc(self.mk_expr(hir::ExprKind::Path(new_path), span));
let args = self.arena.alloc_from_iter(args);
let call = self.arena.alloc(self.mk_expr(hir::ExprKind::Call(callee_path, args), span));
let call = self.mk_expr(hir::ExprKind::Call(callee_path, args), span);

let expr = if let Some((parent, of_trait)) = self.should_wrap_return_value(delegation) {
let res = Res::SelfTyAlias { alias_to: parent.to_def_id(), is_trait_impl: of_trait };
let ident = Ident::new(kw::SelfUpper, span);
let path = self.create_resolved_path(res, ident, span);

// FIXME(fn_delegation): add default `..` for all other fields.
let initializer = hir::ExprKind::Struct(
self.arena.alloc(path),
self.arena.alloc_slice(&[hir::ExprField {
hir_id: self.next_id(),
is_shorthand: false,
ident: Ident::new(sym::integer(0), span),
expr: self.arena.alloc(call),
span,
}]),
hir::StructTailExpr::None,
);

self.arena.alloc(self.mk_expr(initializer, span))
} else {
self.arena.alloc(call)
};

let block = self.arena.alloc(hir::Block {
stmts,
expr: Some(call),
expr: Some(expr),
hir_id: self.next_id(),
rules: hir::BlockCheckMode::DefaultBlock,
span,
Expand All @@ -678,6 +701,45 @@ impl<'hir> LoweringContext<'_, 'hir> {
(self.mk_expr(hir::ExprKind::Block(block, None), span), call.hir_id)
}

fn should_wrap_return_value(&self, delegation: &Delegation) -> Option<(LocalDefId, bool)> {
// Heuristic: don't do wrapping if there is no target expression.
if delegation.body.is_none() {
return None;
}

let tcx = self.tcx;
let parent = tcx.local_parent(self.owner.def_id);
let parent_kind = tcx.def_kind(parent);

// Apply wrapping for delegations inside
// 1) Trait impls, as the return type of both signature function
// and generated delegation has `Self` generic param returned
// (checked below).
// FIXME(fn_delegation): think of enabling wrapping in more scenarios:
// trait-(impl)-to-free
// trait-(impl)-to-inherent
// inherent-to-free
// 2) Inherent methods when delegating to trait, as we change the type of
// `Self` to type of struct or enum we delegate from.
if !matches!(tcx.def_kind(parent), DefKind::Impl { .. }) {
return None;
}

let is_trait_impl = parent_kind == DefKind::Impl { of_trait: true };

// Check that delegation path resolves to a trait AssocFn, not to a free method.
Some((parent, is_trait_impl)).filter(|_| {
self.get_resolution_id(delegation.id).is_some_and(|id| {
tcx.def_kind(id) == DefKind::AssocFn
// Check that the return type of the callee is `Self` param.
// After previous check we are sure that `sig_id` and `delegation.id`
// point to the same function.
&& tcx.def_kind(tcx.parent(id)) == DefKind::Trait
&& tcx.fn_sig(id).skip_binder().output().skip_binder().is_param(0)
})
})
}

fn process_segment(
&mut self,
span: Span,
Expand Down
13 changes: 11 additions & 2 deletions compiler/rustc_ast_lowering/src/delegation/generics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -588,19 +588,28 @@ impl<'hir> LoweringContext<'_, 'hir> {
p.def_id.to_def_id(),
);

self.create_resolved_path(res, p.name.ident(), p.span)
}

pub(super) fn create_resolved_path(
&mut self,
res: Res,
ident: Ident,
span: Span,
) -> hir::QPath<'hir> {
hir::QPath::Resolved(
None,
self.arena.alloc(hir::Path {
segments: self.arena.alloc_slice(&[hir::PathSegment {
args: None,
hir_id: self.next_id(),
ident: p.name.ident(),
ident,
infer_args: false,
res,
delegation_child_segment: false,
}]),
res,
span: p.span,
span,
}),
)
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_expand/src/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1199,7 +1199,7 @@ pub trait LintStoreExpand {

type LintStoreExpandDyn<'a> = Option<&'a (dyn LintStoreExpand + 'a)>;

#[derive(Debug, Clone, Default)]
#[derive(Debug, Default)]
pub struct ModuleData {
/// Path to the module starting from the crate name, like `my_crate::foo::bar`.
pub mod_path: Vec<Ident>,
Expand Down
5 changes: 2 additions & 3 deletions compiler/rustc_hir_analysis/src/check/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -839,9 +839,8 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(),
tcx.ensure_ok().associated_items(def_id);
if of_trait {
let impl_trait_header = tcx.impl_trait_header(def_id);
res = res.and(tcx.ensure_result().coherent_trait(
impl_trait_header.trait_ref.instantiate_identity().skip_norm_wip().def_id,
));
res = res
.and(tcx.ensure_result().coherent_trait(impl_trait_header.trait_ref.def_id()));

if res.is_ok() {
// Checking this only makes sense if the all trait impls satisfy basic
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_mir_transform/src/check_call_recursion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ impl<'tcx> MirLint<'tcx> for CheckDropRecursion {
if let DefKind::AssocFn = tcx.def_kind(def_id)
&& let Some(impl_id) = tcx.trait_impl_of_assoc(def_id.to_def_id())
&& let trait_ref = tcx.impl_trait_ref(impl_id)
&& tcx.is_lang_item(trait_ref.instantiate_identity().skip_norm_wip().def_id, LangItem::Drop)
&& tcx.is_lang_item(trait_ref.def_id(), LangItem::Drop)
// avoid erroneous `Drop` impls from causing ICEs below
&& let sig = tcx.fn_sig(def_id).instantiate_identity().skip_norm_wip()
&& sig.inputs().skip_binder().len() == 1
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_resolve/src/error_helper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ impl TypoSuggestion {
}

/// A free importable items suggested in case of resolution failure.
#[derive(Debug, Clone)]
#[derive(Debug)]
pub(crate) struct ImportSuggestion {
pub did: Option<DefId>,
pub descr: &'static str,
Expand Down
9 changes: 4 additions & 5 deletions compiler/rustc_resolve/src/imports.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,6 @@ impl<'ra> PendingDecl<'ra> {
}

/// Contains data for specific kinds of imports.
#[derive(Clone)]
pub(crate) enum ImportKind<'ra> {
Single {
/// `source` in `use prefix::source as target`.
Expand Down Expand Up @@ -157,7 +156,7 @@ impl<'ra> std::fmt::Debug for ImportKind<'ra> {
}

/// One import.
#[derive(Debug, Clone)]
#[derive(Debug)]
pub(crate) struct ImportData<'ra> {
pub kind: ImportKind<'ra>,

Expand Down Expand Up @@ -280,7 +279,7 @@ impl<'ra> ImportData<'ra> {
}

/// Records information about the resolution of a name in a namespace of a module.
#[derive(Clone, Debug)]
#[derive(Debug)]
pub(crate) struct NameResolution<'ra> {
/// Single imports that may define the name in the namespace.
/// Imports are arena-allocated, so it's ok to use pointers as keys.
Expand Down Expand Up @@ -377,7 +376,7 @@ pub(crate) mod cycle_detection {

/// An error that may be transformed into a diagnostic later. Used to combine multiple unresolved
/// import errors within the same use tree into a single diagnostic.
#[derive(Debug, Clone)]
#[derive(Debug)]
pub(crate) struct UnresolvedImportError {
pub(crate) span: Span,
pub(crate) label: Option<String>,
Expand All @@ -396,7 +395,7 @@ fn pub_use_of_private_extern_crate_hack(
import: ImportSummary,
decl: Decl<'_>,
) -> Option<LocalDefId> {
match (import.is_single, decl.kind) {
match (import.is_single, &decl.kind) {
(true, DeclKind::Import { import: decl_import, .. })
if let ImportKind::ExternCrate { def_id, .. } = decl_import.kind
&& import.vis.is_public() =>
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_resolve/src/late/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ pub(super) struct MissingLifetime {

/// Description of the lifetimes appearing in a function parameter.
/// This is used to provide a literal explanation to the elision failure.
#[derive(Clone, Debug)]
#[derive(Debug)]
pub(super) struct ElisionFnParameter {
/// The index of the argument in the original definition.
pub index: usize,
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_resolve/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -984,7 +984,7 @@ impl<'ra> fmt::Debug for LocalModule<'ra> {
}

/// Data associated with any name declaration.
#[derive(Clone, Debug)]
#[derive(Debug)]
struct DeclData<'ra> {
kind: DeclKind<'ra>,
ambiguity: CmCell<Option<(Decl<'ra>, bool /*warning*/)>>,
Expand Down Expand Up @@ -1018,7 +1018,7 @@ impl std::hash::Hash for DeclData<'_> {
}

/// Name declaration kind.
#[derive(Clone, Copy, Debug)]
#[derive(Debug)]
enum DeclKind<'ra> {
/// The name declaration is a definition (possibly without a `DefId`),
/// can be provided by source code or built into the language.
Expand Down
6 changes: 6 additions & 0 deletions compiler/rustc_type_ir/src/binder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -448,6 +448,12 @@ impl<I: Interner, T> EarlyBinder<I, T> {
}
}

impl<I: Interner> EarlyBinder<I, ty::TraitRef<I>> {
pub fn def_id(&self) -> I::TraitId {
self.value.def_id
}
}

impl<I: Interner, T> EarlyBinder<I, Option<T>> {
pub fn transpose(self) -> Option<EarlyBinder<I, T>> {
self.value.map(|value| EarlyBinder { value, _tcx: PhantomData })
Expand Down
32 changes: 32 additions & 0 deletions library/core/src/cmp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,10 @@
#![stable(feature = "rust1", since = "1.0.0")]

mod bytewise;
mod clamp;
pub(crate) use bytewise::BytewiseEq;
#[unstable(feature = "clamp_bounds", issue = "147781")]
pub use clamp::ClampBounds;

use self::Ordering::*;
use crate::marker::{Destruct, PointeeSized};
Expand Down Expand Up @@ -1109,6 +1112,35 @@ pub const trait Ord: [const] Eq + [const] PartialOrd<Self> + PointeeSized {
self
}
}

/// Restrict a value to a certain range.
///
/// This is equal to `max`, `min`, or `clamp`, depending on whether the range is `min..`,
/// `..=max`, or `min..=max`, respectively. Exclusive ranges are not permitted.
///
/// # Panics
///
/// Panics on `min..=max` if `min > max`.
///
/// # Examples
///
/// ```
/// #![feature(clamp_to)]
/// assert_eq!((-3).clamp_to(-2..=1), -2);
/// assert_eq!(0.clamp_to(-2..=1), 0);
/// assert_eq!(2.clamp_to(..=1), 1);
/// assert_eq!(5.clamp_to(7..), 7);
/// ```
#[must_use]
#[inline]
#[unstable(feature = "clamp_to", issue = "147781")]
fn clamp_to<R>(self, range: R) -> Self
where
Self: Sized + [const] Destruct,
R: [const] ClampBounds<Self>,
{
range.clamp(self)
}
}

/// Derive macro generating an impl of the trait [`Ord`].
Expand Down
Loading
Loading