Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
3631ff3
make semicolon_in_expressions_from_non_local_macros not report-in-deps
RalfJung Sep 14, 2026
70ed6c3
Get `inputs_hir` directly from `decl`
JonathanBrouwer Oct 2, 2026
1b5f48e
Fix extra spaces in integer format_into docs
cellrishi-code Oct 4, 2026
1d7bfc7
Update GitHub Actions to v26
renovate-bot Oct 5, 2026
a9b28d3
Skip optional asserts in SsaRangePropagation
saethlin Oct 5, 2026
4bfa46e
bump Windows CI LLVM to 22.1.8
Walnut356 Oct 5, 2026
2d0258e
moves rustc_legacy_const_generics checks into attribute parsing
ssenthilnathan3 Oct 5, 2026
b317a6a
fixes legacy const generics finalize_check signature
ssenthilnathan3 Oct 5, 2026
f998e4a
fix: panic on unreasonable cases instead of going silent
ssenthilnathan3 Oct 5, 2026
6e4e68f
document rustc_comptime
mejrs Oct 5, 2026
f20f0c4
rustc_ast_lowering: track implicit Self via explicit flag instead of …
paradoxicalguy Sep 30, 2026
e95998b
continue crashes tests next-solver work
lcnr Oct 5, 2026
8391ea0
more crashes tests
lcnr Oct 5, 2026
51f1093
more crashes tests
lcnr Oct 5, 2026
7f2478a
more crashes tests + next-solver test migration
lcnr Oct 5, 2026
2df0ee6
more crashes migration
lcnr Oct 5, 2026
471b6d2
more crashes migration
lcnr Oct 5, 2026
a108fb6
more crashes migration
lcnr Oct 5, 2026
38c6c1f
more crashes migration + move tests
lcnr Oct 5, 2026
3ddbe06
yeet duplicate test
lcnr Oct 5, 2026
438196a
remove duplicate test
lcnr Oct 5, 2026
612d3d9
more crashes migration
lcnr Oct 5, 2026
adfb5d3
Fix an issue for clippy's `search_is_some` with the next-solver
ShoyuVanilla Oct 5, 2026
59df601
Add a test for suboptimal diagnostics
ShoyuVanilla Oct 5, 2026
2c9ced6
Rollup merge of #163364 - RalfJung:semicolon-no-report-in-deps, r=mat…
JonathanBrouwer Oct 5, 2026
14af779
Rollup merge of #163531 - paradoxicalguy:infer-indices-clean, r=petro…
JonathanBrouwer Oct 5, 2026
b8d1869
Rollup merge of #163770 - mejrs:document_rustc_comptime, r=oli-obk
JonathanBrouwer Oct 5, 2026
d7738b8
Rollup merge of #163780 - saethlin:rangeprop-asserts, r=dianqk
JonathanBrouwer Oct 5, 2026
721eaf0
Rollup merge of #163785 - Walnut356:windows_ci_llvm22, r=Kobzol
JonathanBrouwer Oct 5, 2026
431aebf
Rollup merge of #163796 - lcnr:crashes-migration, r=lqd
JonathanBrouwer Oct 5, 2026
43abb24
Rollup merge of #163646 - JonathanBrouwer:get-params-from-decl, r=Box…
JonathanBrouwer Oct 5, 2026
9a9b3f1
Rollup merge of #163733 - cellrishi-code:fix-format-into-doc-spaces, …
JonathanBrouwer Oct 5, 2026
e642b4f
Rollup merge of #163773 - renovate-bot:renovate/major-github-actions,…
JonathanBrouwer Oct 5, 2026
9deb169
Rollup merge of #163787 - ssenthilnathan3:move-legacy-const-generics-…
JonathanBrouwer Oct 5, 2026
45e8c52
Rollup merge of #163810 - ShoyuVanilla:clippy-new-solver-fix, r=lcnr
JonathanBrouwer Oct 5, 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
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ jobs:
# If you want to modify CI jobs, take a look at src/ci/github-actions/jobs.yml.
calculate_matrix:
name: Calculate job matrix
runs-on: ubuntu-24.04-arm
runs-on: ubuntu-26.04-arm
outputs:
jobs: ${{ steps.jobs.outputs.jobs }}
run_type: ${{ steps.jobs.outputs.run_type }}
Expand Down Expand Up @@ -309,7 +309,7 @@ jobs:
# This job is used to publish toolstate for successful auto builds.
outcome:
name: publish toolstate
runs-on: ubuntu-24.04
runs-on: ubuntu-26.04
needs: [ calculate_matrix, job ]
if: ${{ needs.calculate_matrix.outputs.run_type == 'auto' }}
environment: ${{ (github.repository == 'rust-lang/rust' && 'bors') || '' }}
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/ghcr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ on:
jobs:
mirror:
name: DockerHub mirror
runs-on: ubuntu-24.04
runs-on: ubuntu-26.04
if: github.repository == 'rust-lang/rust'
permissions:
# Needed to write to the ghcr.io registry
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/post-merge.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ on:

jobs:
analysis:
runs-on: ubuntu-24.04
runs-on: ubuntu-26.04
if: github.repository == 'rust-lang/rust'
permissions:
pull-requests: write
Expand Down
58 changes: 44 additions & 14 deletions compiler/rustc_ast_lowering/src/delegation/generics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ pub(super) struct DelegationGenerics<T> {
data: T,
pos: GenericsPosition,
trait_impl: bool,
has_implicit_self: bool,
}

type TyGenerics<'hir> = Vec<GenericArgSlot<&'hir ty::GenericParamDef>>;
Expand All @@ -44,11 +45,13 @@ impl<'hir> DelegationGenerics<TyGenerics<'hir>> {
params: &'hir [ty::GenericParamDef],
pos: GenericsPosition,
trait_impl: bool,
has_implicit_self: bool,
) -> Self {
DelegationGenerics {
data: params.iter().map(|p| GenericArgSlot::Generate(p, None)).collect(),
pos,
trait_impl,
has_implicit_self,
}
}
}
Expand Down Expand Up @@ -92,6 +95,7 @@ pub(super) struct GenericsGenerationResults<'hir> {
pub(super) struct DelegationGenericArgsIterator<'hir> {
index: usize = Default::default(),
params: &'hir [hir::GenericParam<'hir>],
has_implicit_self: bool,
}

/// During generic args propagation we need to create generic args
Expand All @@ -112,10 +116,10 @@ impl<'hir> DelegationGenericArgsIterator<'hir> {
}

let p = self.params[self.index];
let is_implicit_self = self.has_implicit_self && self.index == 0;
self.index += 1;

// Skip self generic arg, we do not need to propagate it.
if p.name.ident().name == kw::SelfUpper || p.is_impl_trait() {
if is_implicit_self || p.is_impl_trait() {
continue;
}

Expand Down Expand Up @@ -173,6 +177,7 @@ impl<'hir> HirOrTyGenerics<'hir> {
data: params,
pos: ty.pos,
trait_impl: ty.trait_impl,
has_implicit_self: ty.has_implicit_self,
});
}
}
Expand All @@ -189,9 +194,11 @@ impl<'hir> HirOrTyGenerics<'hir> {
HirOrTyGenerics::Ty(_) => {
bug!("attempting to get generic args before uplifting to HIR")
}
HirOrTyGenerics::Hir(hir) => {
DelegationGenericArgsIterator { params: hir.data.params, .. }
}
HirOrTyGenerics::Hir(hir) => DelegationGenericArgsIterator {
params: hir.data.params,
has_implicit_self: hir.has_implicit_self,
..
},
}
}

Expand Down Expand Up @@ -380,13 +387,21 @@ impl<'hir> DelegationResolver<'_, 'hir> {
if trait_impl {
// Considering parent generics, during signature inheritance
// we will take those args that are in trait impl header trait ref.
let parent =
DelegationGenerics { data: vec![], pos: GenericsPosition::Child, trait_impl: true };
let parent = DelegationGenerics {
data: vec![],
pos: GenericsPosition::Child,
trait_impl: true,
has_implicit_self: false,
};

let parent = GenericsGenerationResult::new(parent);

let child =
DelegationGenerics::generate_all(sig_child_params, GenericsPosition::Child, true);
let child = DelegationGenerics::generate_all(
sig_child_params,
GenericsPosition::Child,
true,
false,
);

let child = GenericsGenerationResult::new(child);

Expand All @@ -411,15 +426,20 @@ impl<'hir> DelegationResolver<'_, 'hir> {
),
pos: GenericsPosition::Parent,
trait_impl,
has_implicit_self: generate_free_to_trait_self,
},
ParentSegmentArgs::NotSpecified => DelegationGenerics::generate_all(
&sig_parent_params[usize::from(skip_self)..],
GenericsPosition::Parent,
trait_impl,
generate_free_to_trait_self,
),
ParentSegmentArgs::Invalid => {
DelegationGenerics { data: vec![], pos: GenericsPosition::Parent, trait_impl }
}
ParentSegmentArgs::Invalid => DelegationGenerics {
data: vec![],
pos: GenericsPosition::Parent,
trait_impl,
has_implicit_self: false,
},
};

let child_generics = if let Some(args) = res.child_args {
Expand All @@ -439,9 +459,19 @@ impl<'hir> DelegationResolver<'_, 'hir> {
slots.push(GenericArgSlot::Generate(synth_param, None));
}

DelegationGenerics { data: slots, pos: GenericsPosition::Child, trait_impl }
DelegationGenerics {
data: slots,
pos: GenericsPosition::Child,
trait_impl,
has_implicit_self: false,
}
} else {
DelegationGenerics::generate_all(sig_child_params, GenericsPosition::Child, trait_impl)
DelegationGenerics::generate_all(
sig_child_params,
GenericsPosition::Child,
trait_impl,
false,
)
};

Ok(GenericsGenerationResults {
Expand Down
42 changes: 42 additions & 0 deletions compiler/rustc_attr_ir/src/attribute_docs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -283,3 +283,45 @@ const _: () = ();
/// [#156920]:https://github.com/rust-lang/rust/issues/156920 "`dyn Allocator` together with `Allocator + Clone` requirements is unsound, leading to UB with `Arc`"
/// [#160045]:https://github.com/rust-lang/rust/issues/160045 "`iter::Rev`'s `TrustedLen` impl is unsound with trait objects"
const _: () = ();

#[doc(attribute = "rustc_comptime")]
/// Marks a function as only callable at compile time.
///
/// Unlike `const fn`, which *can* be called from a [const context], comptime functions *must* be
/// called from a const context. It is an error to call a comptime function outside a const context.
///
/// # Example
///
#[doc = include_example!("rustc_comptime")]
///
/// There are many things which only have meaning at compile time and can make use of such
/// functions:
/// - the [`type_info`] feature, for compile time type reflection.
/// - the const heap intrinsics [`const_allocate`] and [`const_deallocate`], at runtime, return a null
/// pointer and do nothing respectively.
/// - intrinsics such as [`size_of`] and friends cause an ICE when they are called at runtime. The
/// stabilized versions of these functions forward to these intrinsics via associated constants on
/// the `SizedTypeProperties` trait.
///
/// At this time,
// < October of 2026 >
/// the primary motivation for comptime functions is the [`type_info`] feature. The constructs
/// in [`mem::type_info`] only makes sense at compile time as during compile time we can simply
/// ask the compiler for whatever information we need. At runtime, though, that cannot be done - to
/// support runtime reflection we would have to create some global table with all the information
/// we might possibly need. This is unfeasible and any (third party wrappers for) "runtime
/// reflection" based on `type_info` would be limited to retrieving information queried in advance
/// at compile time.
///
/// See the [reflection and comptime project goal] for more information about reflection and
/// comptime.
///
/// See [`AttributeKind::RustcComptime`] for the internal representation of this attribute.
///
/// [const context]: https://doc.rust-lang.org/nightly/reference/const_eval.html#const-context
/// [`type_info`]: https://github.com/rust-lang/rust/issues/146922
/// [`const_allocate`]: std::intrinsics::const_allocate
/// [`const_deallocate`]: std::intrinsics::const_deallocate
/// [`mem::type_info`]: std::mem::type_info
/// [reflection and comptime project goal]: https://goals.rust-lang.org/2026/reflection-and-comptime.html
const _: () = ();
2 changes: 1 addition & 1 deletion compiler/rustc_attr_ir/src/data_structures.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1180,7 +1180,7 @@ pub enum AttributeKind {
/// Represents `#[rustc_coinductive]`.
RustcCoinductive,

/// Represents `#[rustc_comptime]`
/// Represents the [`rustc_comptime`](./attribute.rustc_comptime.html) attribute.
RustcComptime(Span),

/// Represents `#[rustc_confusables]`.
Expand Down
44 changes: 43 additions & 1 deletion compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::path::PathBuf;

use rustc_ast::{LitIntType, LitKind, MetaItemLit};
use rustc_ast::{GenericParamKind, ItemKind, LitIntType, LitKind, MetaItemLit};
use rustc_attr_ir::lang_items::LangItem;
use rustc_attr_ir::{
BorrowckGraphvizFormatKind, CguFields, CguKind, RustcCleanAttribute, RustcCleanQueries,
Expand Down Expand Up @@ -169,6 +169,48 @@ impl SingleAttributeParser for RustcLegacyConstGenericsParser {
attr_span: cx.attr_span,
})
}

fn finalize_check(cx: &mut FinalizeCheckContext<'_, '_>, attr_span: Span) {
if cx.target != Target::Fn {
// Invalid targets are already diagnosed by target checking.
return;
}
let item = cx.target_item.expect("missing AST target item for Target::Fn");
let ItemKind::Fn(function) = &item.kind else {
panic!("expected fn AST target item for Target::Fn");
};
let index_list = rustc_attr_ir::find_attr!(cx.parsed_attrs, RustcLegacyConstGenerics { fn_indexes, .. } => fn_indexes)
.expect("missing parsed RustcLegacyConstGenerics attribute in finalize_check");
let generics = &function.generics;

for param in &generics.params {
if !matches!(param.kind, GenericParamKind::Const { .. }) {
cx.emit_err(diagnostics::RustcLegacyConstGenericsOnly {
attr_span,
param_span: param.span(),
});
return;
}
}

if index_list.len() != generics.params.len() {
cx.emit_err(diagnostics::RustcLegacyConstGenericsIndex {
attr_span,
generics_span: generics.span,
});
return;
}

let arg_count = function.sig.decl.inputs.len() + generics.params.len();
for (index, span) in index_list {
if *index >= arg_count {
cx.emit_err(diagnostics::RustcLegacyConstGenericsIndexExceed {
span: *span,
arg_count,
});
}
}
}
}

pub(crate) struct RustcInheritOverflowChecksParser;
Expand Down
35 changes: 35 additions & 0 deletions compiler/rustc_attr_parsing/src/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,41 @@ use rustc_target::spec::TargetTuple;
use crate::AttributeTemplate;
use crate::context::Suggestion;

#[derive(Diagnostic)]
#[diag("#[rustc_legacy_const_generics] functions must only have const generics")]
pub(crate) struct RustcLegacyConstGenericsOnly {
#[primary_span]
pub attr_span: Span,
#[label("non-const generic parameter")]
pub param_span: Span,
}

#[derive(Diagnostic)]
#[diag("#[rustc_legacy_const_generics] must have one index for each generic parameter")]
pub(crate) struct RustcLegacyConstGenericsIndex {
#[primary_span]
pub attr_span: Span,
#[label("generic parameters")]
pub generics_span: Span,
}

#[derive(Diagnostic)]
#[diag("index exceeds number of arguments")]
pub(crate) struct RustcLegacyConstGenericsIndexExceed {
#[primary_span]
#[label(
"there {$arg_count ->
[one] is
*[other] are
} only {$arg_count} {$arg_count ->
[one] argument
*[other] arguments
}"
)]
pub span: Span,
pub arg_count: usize,
}

#[derive(Diagnostic)]
#[diag("`{$name}` attribute cannot be used at crate level")]
pub(crate) struct InvalidAttrAtCrateLevel {
Expand Down
3 changes: 1 addition & 2 deletions compiler/rustc_hir_typeck/src/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,6 @@ pub(super) fn check_fn<'a, 'tcx>(
});

// Add formal parameters.
let inputs_hir = tcx.hir_fn_decl_by_hir_id(fn_id).map(|decl| &decl.inputs);
let inputs_fn = fn_sig.inputs().iter().copied();
for (idx, (param_ty, param)) in inputs_fn.chain(maybe_va_list).zip(body.params).enumerate() {
// We checked the root's signature during wfcheck, but not the child.
Expand All @@ -81,7 +80,7 @@ pub(super) fn check_fn<'a, 'tcx>(
}

// Check the pattern.
let ty: Option<&hir::Ty<'_>> = inputs_hir.and_then(|h| h.get(idx));
let ty: Option<&hir::Ty<'_>> = decl.inputs.get(idx);
let ty_span = ty.map(|ty| ty.span);
fcx.check_pat_top(param.pat, param_ty, ty_span, None, None);
if param.pat.is_never_pattern() {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_lint_defs/src/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3024,7 +3024,7 @@ declare_lint! {
"trailing semicolon in macro body used as expression",
@future_incompatible = FutureIncompatibleInfo {
reason: fcw!(FutureReleaseError #79813),
report_in_deps: true,
report_in_deps: false,
};
}

Expand Down
8 changes: 6 additions & 2 deletions compiler/rustc_mir_transform/src/ssa_range_prop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -155,12 +155,16 @@ impl<'tcx> MutVisitor<'tcx> for RangeSet<'tcx, '_, '_> {
fn visit_terminator(&mut self, terminator: &mut Terminator<'tcx>, location: Location) {
self.super_terminator(terminator, location);
match &terminator.kind {
TerminatorKind::Assert { cond, expected, target, .. }
TerminatorKind::Assert { cond, expected, target, msg, .. }
if let Some(place) = cond.place()
&& self.is_ssa(place) =>
{
let successor = Location { block: *target, statement_index: 0 };
if location.strictly_dominates(successor, &self.dominators) {
if location.strictly_dominates(successor, &self.dominators)
// Don't propagate range information from built-in overflow checks,
// this MIR might be lowered without them!
&& !msg.is_optional_overflow_check()
{
let val = *expected as u128;
let range = WrappingRange { start: val, end: val };
self.insert_range(place, successor, range);
Expand Down
Loading
Loading