Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
0e58273
Merge commit 'bb351cd4ddf59d8a9b5c086a15e41bc6a1c05b5f' into sync_cg_…
bjorn3 Aug 19, 2026
27b8037
Merge branch 'sync_from_rust'
bjorn3 Aug 19, 2026
1aa6289
move CrateType
mejrs Aug 17, 2026
01c4315
Remove LD_STATIC_TLS_EXTRA workaround from FreeBSD CI
0xmuon Aug 21, 2026
945a71a
make `pad_i32` of `PassMode::cast` an integer
folkertdev Jul 29, 2026
9cac33b
Merge pull request #1692 from 0xmuon/fix10
bjorn3 Aug 22, 2026
611b1bf
Sync from rust fb6531d550e0075b9eb9a51464f404805eec87d9
bjorn3 Aug 24, 2026
a299bc1
Rustup to rustc 1.100.0-nightly (fb6531d55 2026-08-23)
bjorn3 Aug 24, 2026
19946d3
Fix rustc test suite
bjorn3 Aug 24, 2026
b5534e2
Fix warning
bjorn3 Aug 24, 2026
e963628
Rollup merge of #160132 - folkertdev:pad-i32-count, r=bjorn3
JonathanBrouwer Aug 24, 2026
2bc05d4
Update to Cranelift 0.135
bjorn3 Aug 6, 2026
98f4067
mir: validate Move call arguments are locals or box derefs
rabindra789 Aug 6, 2026
e960d5e
fix(reborrow): recursive implementation
aapoalas Aug 27, 2026
186d80c
Rollup merge of #159103 - aapoalas:reborrow/fix-borrowed-place, r=oli…
JonathanBrouwer Aug 28, 2026
84963f8
run `extern "tail"` with `byval` argument test
folkertdev Aug 28, 2026
61f4a73
Remove -Zsaturating-float-casts flag
hanna-kruppe Aug 29, 2026
ee07e85
Add intrinsics for integer minimum and maximum
scottmcm Aug 14, 2026
0dc10aa
attach naked function target features to module assembly
folkertdev Aug 6, 2026
52363bd
Cleanup cranelift `codegen_float_intrinsic_call`
N1ark Aug 12, 2026
2bba73b
Make sin, cos, exp, exp2, log, log2, log10 generic
N1ark Aug 17, 2026
7cebc0d
Rollup merge of #137720 - folkertdev:naked-function-target-feature, r…
JonathanBrouwer Sep 1, 2026
7d98fc6
Rollup merge of #160989 - N1ark:08-12-generic-float-intrinsincs, r=fo…
JonathanBrouwer Sep 1, 2026
9a57f7b
Rollup merge of #161971 - hanna-kruppe:rm-flag-satfpcast, r=RalfJung
JonathanBrouwer Sep 1, 2026
82e12d6
Creates new `InlineAsmSize` enum
CrooseGit Jun 15, 2026
98d4b61
Disable inline asm line info cookies when llvm bitcode is saved or LT…
susitsm Jul 30, 2026
18dd4a8
Reduce size of 0027-stdlib-128bit-atomic-operations.patch
bjorn3 Sep 6, 2026
1ae0feb
Sync from rust f248f4038796913873f11ca65b1b901e311c8dae
bjorn3 Sep 6, 2026
ea847bb
Rustup to rustc 1.100.0-nightly (f248f4038 2026-09-05)
bjorn3 Sep 6, 2026
ba9ce94
Fix rustc test suite
bjorn3 Sep 6, 2026
50311dd
Remove stabilized feature gate
bjorn3 Sep 6, 2026
7768834
Add regression test for item-local diagnostic attribute lint levels
chenyukang Sep 7, 2026
5a881f3
Rollup merge of #160197 - susitsm:restrict-inline-asm-cookies, r=petr…
JonathanBrouwer Sep 7, 2026
38e3714
windows-gnu: document libgcc requirement
mati865 Sep 7, 2026
9dee1dc
Update books
rustbot Sep 7, 2026
fa2850e
misc typo fixes
ada4a Aug 24, 2026
2827a30
remove outdated docs
ada4a Aug 24, 2026
0db592d
realize that `bounds` works a bit differently than advertised
ada4a Aug 24, 2026
ada4f67
add tests for `#[derive(GenericTypeVisitable)]` and `bounds`
ada4a Sep 7, 2026
2c4265a
Supporting delegations to inherent functions
aerooneqq Sep 8, 2026
8463342
docs(time): replace "method" with "function"
sorairolake Sep 8, 2026
0c1141f
Sync from rust cea272fa356e94bd2ee2cadf376630aa0683867a
bjorn3 Sep 8, 2026
9bf6ad8
Fix duplicate thanks entry
JonathanBrouwer Sep 8, 2026
db693f7
Rustup to rustc 1.100.0-nightly (cea272fa3 2026-09-07)
bjorn3 Sep 8, 2026
a2b78f2
Merge commit 'db693f7dbcfab9af2a89b703096f692417e2f756' into sync_cg_…
bjorn3 Sep 8, 2026
951ad7b
Fix divergence with the cg_clif repo
bjorn3 Sep 8, 2026
f6c65c2
Rollup merge of #162470 - bjorn3:sync_cg_clif-2026-09-08, r=bjorn3
JonathanBrouwer Sep 8, 2026
2fc58e7
Rollup merge of #160505 - aerooneqq:delegation-inherent-methods, r=pe…
JonathanBrouwer Sep 8, 2026
f38a57e
Rollup merge of #160651 - rabindra789:fix/mir-verifier-move-call-args…
JonathanBrouwer Sep 8, 2026
dba3939
Rollup merge of #161806 - ada4a:push-olrruxoktqnl, r=JonathanBrouwer
JonathanBrouwer Sep 8, 2026
7c3d1c2
Rollup merge of #161912 - folkertdev:extern-tail-x86-byval, r=WaffleL…
JonathanBrouwer Sep 8, 2026
e4b0e9f
Rollup merge of #162435 - mati865:windows-gnu-libgcc-doc, r=nnethercote
JonathanBrouwer Sep 8, 2026
b9e6153
Rollup merge of #162439 - rustbot:docs-update, r=traviscross
JonathanBrouwer Sep 8, 2026
d748c32
Rollup merge of #162451 - chenyukang:yukang-fix-135772-local-diagnost…
JonathanBrouwer Sep 8, 2026
46351a5
Rollup merge of #162459 - sorairolake:fix-method-to-function, r=Darksonn
JonathanBrouwer Sep 8, 2026
c7a95b9
Rollup merge of #162465 - JonathanBrouwer:fix-mailmap, r=JonathanBrouwer
JonathanBrouwer Sep 8, 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 .mailmap
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,7 @@ John Van Enk <vanenkj@gmail.com>
Jon Gjengset <jon@thesquareplanet.com> <jongje@amazon.com>
Jonas Tepe <jonasprogrammer@gmail.com>
Jonathan Bailey <jbailey@mozilla.com> <jbailey@jbailey-20809.local>
Jonathan Brouwer <jonathantbrouwer@gmail.com> <jonathan.brouwer@technolution.nl>
Jonathan Chan Kwan Yin <sofe2038@gmail.com>
Jonathan L <Xmasreturns@users.noreply.github.com>
Jonathan S <gereeter@gmail.com> Jonathan S <gereeter+code@gmail.com>
Expand Down
8 changes: 8 additions & 0 deletions compiler/rustc_ast/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,14 @@ impl GenericArg {
GenericArg::Const(ct) => ct.value.span,
}
}

pub fn is_maybe_parenthesised_infer(&self) -> bool {
match self {
GenericArg::Lifetime(lt) => lt.ident.name == kw::UnderscoreLifetime,
GenericArg::Type(ty) => ty.is_maybe_parenthesised_infer(),
GenericArg::Const(_) => false,
}
}
}

/// A path like `Foo<'a, T>`.
Expand Down
93 changes: 76 additions & 17 deletions compiler/rustc_ast_lowering/src/delegation/generics.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use std::assert_matches;

use hir::HirId;
use hir::def::{DefKind, Res};
use rustc_ast::*;
Expand All @@ -11,7 +13,10 @@ use rustc_span::{ErrorGuaranteed, Ident, Span, sym};

use crate::LoweringContext;
use crate::delegation::resolution::resolver::DelegationResolver;
use crate::diagnostics::DelegationInfersMismatch;
use crate::diagnostics::{
DelegationInfersMismatch, DelegationToInherentImplMustContainParentGenerics,
DelegationToInherentImplParentContainsInfer,
};

#[derive(Debug, Clone, Copy, Eq, PartialEq)]
pub(super) enum GenericsPosition {
Expand All @@ -25,6 +30,7 @@ pub(super) enum GenericArgSlot<T> {
Generate(T, Option<usize> /* Infer arg index from AST */),
}

#[derive(Debug)]
pub(super) struct DelegationGenerics<T> {
data: T,
pos: GenericsPosition,
Expand Down Expand Up @@ -57,11 +63,13 @@ impl<'hir> DelegationGenerics<TyGenerics<'hir>> {
/// meaning we did not propagate them and thus we do not need to generate generic params
/// (i.e., method call scenarios), in such a case this approach helps
/// a lot as if `into_hir_generics` will not be called then uplifting will not happen.
#[derive(Debug)]
pub(super) enum HirOrTyGenerics<'hir> {
Ty(DelegationGenerics<TyGenerics<'hir>>),
Hir(DelegationGenerics<&'hir hir::Generics<'hir>>),
}

#[derive(Debug)]
pub(super) struct GenericsGenerationResult<'hir> {
pub(super) generics: HirOrTyGenerics<'hir>,
pub(super) args_segment_id: HirId,
Expand All @@ -80,6 +88,7 @@ pub(super) struct GenericsGenerationResults<'hir> {
pub(super) self_ty_propagation_kind: Option<hir::DelegationSelfTyPropagationKind>,
}

#[derive(Debug)]
pub(super) struct DelegationGenericArgsIterator<'hir> {
index: usize = Default::default(),
params: &'hir [hir::GenericParam<'hir>],
Expand Down Expand Up @@ -145,6 +154,7 @@ impl<'hir> DelegationGenericArgsIterator<'hir> {
ctx: &mut LoweringContext<'_, 'hir>,
) -> Vec<hir::GenericArg<'hir>> {
let mut args = vec![];

while let Some(arg) = self.next(ctx, |ctx| ctx.next_id()) {
args.push(arg);
}
Expand Down Expand Up @@ -238,6 +248,7 @@ impl<'hir> GenericsGenerationResult<'hir> {
}
}

#[derive(Debug)]
enum ParentSegmentArgs<'a> {
/// Parent segment is valid and generic args are specified:
/// `reuse Trait::<'static, ()>::foo;`.
Expand Down Expand Up @@ -273,7 +284,7 @@ struct GenericsResolution<'a, 'tcx> {
/// `reuse <_ as Trait>::foo;`.
qself_is_infer: bool,
/// Whether we should generate `Self` generic param.
generate_self: bool,
generate_free_to_trait_self: bool,
}

impl<'hir> DelegationResolver<'_, 'hir> {
Expand All @@ -288,8 +299,7 @@ impl<'hir> DelegationResolver<'_, 'hir> {
let delegation_in_free_ctx =
!matches!(delegation_parent_kind, DefKind::Trait | DefKind::Impl { .. });

let sig_parent = tcx.parent(sig_id);
let sig_in_trait = matches!(tcx.def_kind(sig_parent), DefKind::Trait);
let sig_in_trait = matches!(tcx.def_kind(tcx.parent(sig_id)), DefKind::Trait);
let free_to_trait_delegation = delegation_in_free_ctx && sig_in_trait;

let mut sig_parent_params: &[ty::GenericParamDef] = &[];
Expand All @@ -301,8 +311,13 @@ impl<'hir> DelegationResolver<'_, 'hir> {

let parent_args = if let [.., parent_segment, _] = &delegation.path.segments[..] {
let res = self.get_resolution_id(parent_segment.id)?;
if matches!(tcx.def_kind(res), DefKind::Trait | DefKind::TraitAlias) {
sig_parent_params = &tcx.generics_of(sig_parent).own_params;
if !matches!(tcx.def_kind(res), DefKind::Mod) {
assert_matches!(
tcx.def_kind(res),
DefKind::Trait | DefKind::Struct | DefKind::Enum
);

sig_parent_params = &tcx.generics_of(res).own_params;
self.get_user_args(parent_segment)
.map(|args| ParentSegmentArgs::Specified(args))
.unwrap_or(ParentSegmentArgs::NotSpecified)
Expand All @@ -319,7 +334,8 @@ impl<'hir> DelegationResolver<'_, 'hir> {
qself_is_none,
qself_is_infer,
free_to_trait_delegation,
generate_self: free_to_trait_delegation && (qself_is_none || qself_is_infer),
generate_free_to_trait_self: free_to_trait_delegation
&& (qself_is_none || qself_is_infer),
trait_impl: matches!(delegation_parent_kind, DefKind::Impl { of_trait: true }),
sig_child_params: &tcx.generics_of(sig_id).own_params,
child_args: self.get_user_args(
Expand Down Expand Up @@ -349,10 +365,11 @@ impl<'hir> DelegationResolver<'_, 'hir> {
&self,
delegation: &Delegation,
sig_id: DefId,
span: Span,
) -> Result<GenericsGenerationResults<'hir>, ErrorGuaranteed> {
let res @ GenericsResolution {
trait_impl,
generate_self,
generate_free_to_trait_self,
sig_child_params,
sig_parent_params,
..
Expand All @@ -376,20 +393,27 @@ impl<'hir> DelegationResolver<'_, 'hir> {
return Ok(GenericsGenerationResults { parent, child, self_ty_propagation_kind: None });
}

self.check_delegation_to_inherent_impl(&res.parent_args, sig_id, span)?;

let tcx = self.tcx();

// If parent is inherent impl then there is no `Self` param to skip, so add additional check.
let skip_self =
!generate_free_to_trait_self && tcx.def_kind(tcx.parent(sig_id)) == DefKind::Trait;

let parent_generics = match res.parent_args {
ParentSegmentArgs::Specified(args) => DelegationGenerics {
data: Self::create_slots_from_args(
tcx,
args,
&sig_parent_params[usize::from(!generate_self)..],
generate_self,
&sig_parent_params[usize::from(skip_self)..],
generate_free_to_trait_self,
),
pos: GenericsPosition::Parent,
trait_impl,
},
ParentSegmentArgs::NotSpecified => DelegationGenerics::generate_all(
&sig_parent_params[usize::from(!generate_self)..],
&sig_parent_params[usize::from(skip_self)..],
GenericsPosition::Parent,
trait_impl,
),
Expand Down Expand Up @@ -437,6 +461,46 @@ impl<'hir> DelegationResolver<'_, 'hir> {
})
}

fn check_delegation_to_inherent_impl(
&self,
parent_args: &ParentSegmentArgs<'_>,
sig_id: DefId,
span: Span,
) -> Result<(), ErrorGuaranteed> {
let tcx = self.tcx();

if !(tcx.def_kind(sig_id) == DefKind::AssocFn
&& matches!(tcx.def_kind(tcx.parent(sig_id)), DefKind::Impl { of_trait: false }))
{
return Ok(());
}

let ty::Adt(def, _) = tcx.type_of(tcx.parent(sig_id)).skip_binder().kind() else {
unreachable!("parent of inherent function can be only struct or enum")
};

match parent_args {
ParentSegmentArgs::Invalid => unreachable!(),
ParentSegmentArgs::Specified(args) => args
.args
.iter()
.all(|arg| {
let AngleBracketedArg::Arg(arg) = arg else { return false };
!arg.is_maybe_parenthesised_infer()
})
.ok_or_else(|| {
self.tcx().dcx().emit_err(DelegationToInherentImplParentContainsInfer { span })
}),
ParentSegmentArgs::NotSpecified => match tcx.generics_of(def.did()).own_params.len() {
0 => Ok(()),
_ => Err(self
.tcx()
.dcx()
.emit_err(DelegationToInherentImplMustContainParentGenerics { span })),
},
}
}

/// Generates generic argument slots for user-specified `args` and
/// generic `params` of the signature function. This function checks whether
/// there are infers (`kw::UnderscoreLifetime` or `kw::Underscore`) in
Expand All @@ -459,12 +523,7 @@ impl<'hir> DelegationResolver<'_, 'hir> {
let params = &params[usize::from(add_first_self)..];
for (idx, (arg, param)) in args.args.iter().zip(params).enumerate() {
let AngleBracketedArg::Arg(arg) = arg else { continue };

let is_infer = match arg {
GenericArg::Lifetime(lt) => lt.ident.name == kw::UnderscoreLifetime,
GenericArg::Type(ty) => ty.is_maybe_parenthesised_infer(),
GenericArg::Const(_) => false,
};
let is_infer = arg.is_maybe_parenthesised_infer();

// If `'_` is used instead of `_` (or vice versa) we emit a meaningful
// error instead of processing this infer or leaving it as is for signature
Expand Down
37 changes: 34 additions & 3 deletions compiler/rustc_ast_lowering/src/delegation/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ use rustc_ast as ast;
use rustc_ast::*;
use rustc_hir::attrs::lang_items::LangItem;
use rustc_hir::def::DefKind;
use rustc_hir::{self as hir, FnDeclFlags};
use rustc_hir::{self as hir, FnDeclFlags, QPath};
use rustc_middle::ty::Asyncness;
use rustc_span::def_id::DefId;
use rustc_span::symbol::kw;
Expand All @@ -62,7 +62,7 @@ use crate::{

mod attributes;
mod generics;
mod resolution;
pub(crate) mod resolution;

pub(crate) struct DelegationResults<'hir> {
pub body_id: hir::BodyId,
Expand Down Expand Up @@ -416,7 +416,37 @@ impl<'hir> LoweringContext<'_, 'hir> {

hir::QPath::Resolved(ty, self.arena.alloc(new_path))
}
hir::QPath::TypeRelative(..) => unreachable!("until inherent methods are supported"),
hir::QPath::TypeRelative(mut ty, segment) => {
let mut segment = self.process_segment(span, segment, &mut generics.child);
segment.res = Res::Def(self.tcx.def_kind(res.call_path_res), res.call_path_res);

let ty_hir_id = ty.hir_id;

// Propagating child generics if needed.
ty = if let hir::TyKind::Path(QPath::Resolved(ty, path)) = ty.kind {
let mut new_path = path.clone();

new_path.segments = self.arena.alloc_from_iter(
new_path.segments.iter().enumerate().map(|(idx, segment)| {
if idx + 1 == new_path.segments.len() {
self.process_segment(span, segment, &mut generics.parent)
} else {
segment.clone()
}
}),
);

self.arena.alloc(hir::Ty {
hir_id: ty_hir_id,
span,
kind: hir::TyKind::Path(QPath::Resolved(ty, self.arena.alloc(new_path))),
})
} else {
ty
};

hir::QPath::TypeRelative(ty, self.arena.alloc(segment))
}
};

if let Some(hir::DelegationSelfTyPropagationKind::SelfTy(id)) =
Expand Down Expand Up @@ -491,6 +521,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
result.generics.into_hir_generics(self, span);

let mut segment = segment.clone();

let mut args_iter = result.generics.create_args_iterator();

let new_args = segment
Expand Down
Loading
Loading