Skip to content

Conversation

@oli-obk
Copy link
Contributor

@oli-obk oli-obk commented Nov 3, 2025

Some constifications are annoying because we need to repeat T: Trait bounds from an impl block on the individual constified const fns as T: [const] Trait. We've brainstormed solutions before, and one would be to have separate const impl blocks or sth. However the final syntax will look, I decided to just impl this syntax and either have sth nice on nightly to work with or at least move the discussion along.

Also interacts with the discussion around impl const Trait for Type vs const impl Trait for Type, as we may want to use the latter to keep inherent and trait impls in sync (unless we come up with even another scheme).

  • rustdoc + tests
  • macro stability /regression tests

r? @fee1-dead

cc @traviscross @rust-lang/project-const-traits

@rustbot
Copy link
Collaborator

rustbot commented Nov 3, 2025

Some changes occurred in src/tools/clippy

cc @rust-lang/clippy

Some changes occurred to the CTFE machinery

cc @RalfJung, @oli-obk, @lcnr

Some changes occurred in src/tools/rustfmt

cc @rust-lang/rustfmt

Changes to the size of AST and/or HIR nodes.

cc @nnethercote

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-clippy Relevant to the Clippy team. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-rustfmt Relevant to the rustfmt team, which will review and decide on the PR/issue. labels Nov 3, 2025
@rust-log-analyzer

This comment has been minimized.

Copy link
Contributor

@traviscross traviscross left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me, including from the side of the lang experiment, as the lang champion.

View changes since this review

Comment on lines 1316 to +1322
fn should_encode_constness(def_kind: DefKind) -> bool {
match def_kind {
DefKind::Fn | DefKind::AssocFn | DefKind::Closure | DefKind::Ctor(_, CtorKind::Fn) => true,
DefKind::Fn
| DefKind::AssocFn
| DefKind::Closure
| DefKind::Ctor(_, CtorKind::Fn)
| DefKind::Impl { of_trait: false } => true,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see something asymmetric here, and this is something we might want to address either here or some time later.

We only encode impl methods' constness for trait impls and those are inherited from the impl, but is it not better to just look at the parent and only encode constness once? Since we're going with the whole-trait whole-impl approach anyways.

In the other direction, we should not encode const impl also and have all the assocs encode their constness.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking into this I realized we encode even NotConst in metadata. So all functions get the value encoded, even if we could just encode it if Maybe or Always and treat the lack of a value as NotConst

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will look into this metadata encoding thing later

Comment on lines +2561 to +2600
return Some(true);
}
if ALL_QUALS.iter().any(|&qual| token.is_keyword(qual)) {
// Ok, we found a legal keyword, keep looking for `impl`
return None;
}
Some(false)
});
if let Some(ret) = action {
return ret;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wonder if using ControlFlow here would be more clearer

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not by much. Tho I would love it if I could ? away a Break(T) in a function that returns T

Comment on lines 990 to +991
if let Some(of_trait) = of_trait.as_deref() {
result.push_str(format_constness_right(of_trait.constness));
result.push_str(format_constness_right(*constness));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

are we not going to format impl const Tr to const impl Tr? Feels like it should be placed at the earlier places now.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Happy to go all the way in one PR, just wanted to change as little as possible

@rustbot rustbot added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Nov 4, 2025
@fee1-dead
Copy link
Member

@bors try @rust-timer queue

@rust-timer

This comment has been minimized.

@rust-bors

This comment has been minimized.

rust-bors bot added a commit that referenced this pull request Nov 4, 2025
@rustbot rustbot added the S-waiting-on-perf Status: Waiting on a perf run to be completed. label Nov 4, 2025
@rust-bors
Copy link

rust-bors bot commented Nov 4, 2025

☀️ Try build successful (CI)
Build commit: cb034f2 (cb034f2a46aa06b8466754d9310106afca386763, parent: e5efc336720901420a8891dcdb67ca0a475dc03c)

@rust-timer

This comment has been minimized.

@rust-timer
Copy link
Collaborator

Finished benchmarking commit (cb034f2): comparison URL.

Overall result: ❌ regressions - no action needed

Benchmarking this pull request means it may be perf-sensitive – we'll automatically label it not fit for rolling up. You can override this, but we strongly advise not to, due to possible changes in compiler perf.

@bors rollup=never
@rustbot label: -S-waiting-on-perf -perf-regression

Instruction count

Our most reliable metric. Used to determine the overall result above. However, even this metric can be noisy.

mean range count
Regressions ❌
(primary)
- - 0
Regressions ❌
(secondary)
0.5% [0.5%, 0.6%] 3
Improvements ✅
(primary)
- - 0
Improvements ✅
(secondary)
- - 0
All ❌✅ (primary) - - 0

Max RSS (memory usage)

Results (primary -1.0%, secondary -0.7%)

A less reliable metric. May be of interest, but not used to determine the overall result above.

mean range count
Regressions ❌
(primary)
- - 0
Regressions ❌
(secondary)
0.8% [0.8%, 0.9%] 3
Improvements ✅
(primary)
-1.0% [-1.0%, -1.0%] 1
Improvements ✅
(secondary)
-5.5% [-5.5%, -5.5%] 1
All ❌✅ (primary) -1.0% [-1.0%, -1.0%] 1

Cycles

Results (secondary 0.2%)

A less reliable metric. May be of interest, but not used to determine the overall result above.

mean range count
Regressions ❌
(primary)
- - 0
Regressions ❌
(secondary)
2.4% [1.5%, 3.0%] 5
Improvements ✅
(primary)
- - 0
Improvements ✅
(secondary)
-5.5% [-7.6%, -3.3%] 2
All ❌✅ (primary) - - 0

Binary size

This benchmark run did not return any relevant results for this metric.

Bootstrap: 473.413s -> 473.703s (0.06%)
Artifact size: 390.72 MiB -> 390.78 MiB (0.01%)

@rustbot rustbot removed the S-waiting-on-perf Status: Waiting on a perf run to be completed. label Nov 5, 2025
@fmease fmease added F-const_trait_impl `#![feature(const_trait_impl)]` PG-const-traits Project group: Const traits labels Nov 8, 2025
@bors
Copy link
Collaborator

bors commented Nov 9, 2025

☔ The latest upstream changes (presumably #139558) made this pull request unmergeable. Please resolve the merge conflicts.

@fee1-dead
Copy link
Member

No idea why include-blob of all things regressed. Looks like just noise from the history, so overall this is perf neutral.

I'm happy to land this, and I am happy to do the followup rustdoc work (making rustdoc think of each method as const and inheriting the const stability, etc)

@oli-obk oli-obk force-pushed the inherent-const-impl branch from d780ac6 to 7e3ccca Compare November 18, 2025 09:20
@rustbot
Copy link
Collaborator

rustbot commented Nov 18, 2025

This PR was rebased onto a different main commit. Here's a range-diff highlighting what actually changed.

Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers.

@rust-log-analyzer

This comment has been minimized.

@oli-obk oli-obk force-pushed the inherent-const-impl branch from 7e3ccca to b41c2a2 Compare November 18, 2025 16:01
@fee1-dead
Copy link
Member

Hopefully there is no conflict...

@bors r+

@bors
Copy link
Collaborator

bors commented Nov 18, 2025

📌 Commit b41c2a2 has been approved by fee1-dead

It is now in the queue for this repository.

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Nov 18, 2025
@bors
Copy link
Collaborator

bors commented Nov 19, 2025

⌛ Testing commit b41c2a2 with merge 6159a44...

@bors
Copy link
Collaborator

bors commented Nov 19, 2025

☀️ Test successful - checks-actions
Approved by: fee1-dead
Pushing 6159a44 to main...

@bors bors added the merged-by-bors This PR was explicitly merged by bors. label Nov 19, 2025
@bors bors merged commit 6159a44 into rust-lang:main Nov 19, 2025
12 checks passed
@rustbot rustbot added this to the 1.93.0 milestone Nov 19, 2025
@github-actions
Copy link
Contributor

What is this? This is an experimental post-merge analysis report that shows differences in test outcomes between the merged PR and its parent PR.

Comparing 7c2c3c0 (parent) -> 6159a44 (this PR)

Test differences

Show 310 test diffs

Stage 0

  • errors::verify_ast_passes_abi_cannot_be_coroutine_67: pass -> [missing] (J0)
  • errors::verify_ast_passes_abi_custom_safe_foreign_function_65: pass -> [missing] (J0)
  • errors::verify_ast_passes_abi_must_not_have_parameters_or_return_type_68: pass -> [missing] (J0)
  • errors::verify_ast_passes_abi_must_not_have_return_type_70: [missing] -> pass (J0)
  • errors::verify_ast_passes_abi_x86_interrupt_70: pass -> [missing] (J0)
  • errors::verify_ast_passes_assoc_const_without_body_10: pass -> [missing] (J0)
  • errors::verify_ast_passes_assoc_const_without_body_11: [missing] -> pass (J0)
  • errors::verify_ast_passes_assoc_type_without_body_12: pass -> [missing] (J0)
  • errors::verify_ast_passes_assoc_type_without_body_13: [missing] -> pass (J0)
  • errors::verify_ast_passes_async_fn_in_const_trait_or_trait_impl_2: [missing] -> pass (J0)
  • errors::verify_ast_passes_auto_generic_34: [missing] -> pass (J0)
  • errors::verify_ast_passes_auto_items_35: pass -> [missing] (J0)
  • errors::verify_ast_passes_auto_super_lifetime_34: pass -> [missing] (J0)
  • errors::verify_ast_passes_auto_super_lifetime_35: [missing] -> pass (J0)
  • errors::verify_ast_passes_c_variadic_bad_naked_extern_29: pass -> [missing] (J0)
  • errors::verify_ast_passes_const_and_c_variadic_52: pass -> [missing] (J0)
  • errors::verify_ast_passes_const_and_c_variadic_53: [missing] -> pass (J0)
  • errors::verify_ast_passes_const_and_coroutine_51: pass -> [missing] (J0)
  • errors::verify_ast_passes_const_bound_trait_object_51: [missing] -> pass (J0)
  • errors::verify_ast_passes_const_without_body_14: [missing] -> pass (J0)
  • errors::verify_ast_passes_coroutine_and_c_variadic_54: [missing] -> pass (J0)
  • errors::verify_ast_passes_extern_invalid_safety_16: pass -> [missing] (J0)
  • errors::verify_ast_passes_extern_item_ascii_25: pass -> [missing] (J0)
  • errors::verify_ast_passes_extern_types_cannot_22: [missing] -> pass (J0)
  • errors::verify_ast_passes_extern_without_abi_64: [missing] -> pass (J0)
  • errors::verify_ast_passes_fn_body_extern_23: pass -> [missing] (J0)
  • errors::verify_ast_passes_fn_body_extern_24: [missing] -> pass (J0)
  • errors::verify_ast_passes_fn_param_forbidden_attr_7: pass -> [missing] (J0)
  • errors::verify_ast_passes_fn_param_forbidden_attr_8: [missing] -> pass (J0)
  • errors::verify_ast_passes_fn_ptr_invalid_safety_18: pass -> [missing] (J0)
  • errors::verify_ast_passes_fn_ptr_invalid_safety_19: [missing] -> pass (J0)
  • errors::verify_ast_passes_forbidden_const_param_4: [missing] -> pass (J0)
  • errors::verify_ast_passes_generic_default_trailing_49: [missing] -> pass (J0)
  • errors::verify_ast_passes_incompatible_features_56: pass -> [missing] (J0)
  • errors::verify_ast_passes_incompatible_features_57: [missing] -> pass (J0)
  • errors::verify_ast_passes_item_underscore_31: [missing] -> pass (J0)
  • errors::verify_ast_passes_missing_unsafe_on_extern_44: pass -> [missing] (J0)
  • errors::verify_ast_passes_module_nonascii_32: pass -> [missing] (J0)
  • errors::verify_ast_passes_negative_bound_not_supported_58: [missing] -> pass (J0)
  • errors::verify_ast_passes_nested_impl_trait_38: pass -> [missing] (J0)
  • errors::verify_ast_passes_nested_lifetimes_50: [missing] -> pass (J0)
  • errors::verify_ast_passes_nomangle_ascii_32: [missing] -> pass (J0)
  • errors::verify_ast_passes_obsolete_auto_41: pass -> [missing] (J0)
  • errors::verify_ast_passes_obsolete_auto_42: [missing] -> pass (J0)
  • errors::verify_ast_passes_static_without_body_14: pass -> [missing] (J0)
  • errors::verify_ast_passes_trait_object_single_bound_38: [missing] -> pass (J0)
  • errors::verify_ast_passes_unsafe_negative_impl_42: pass -> [missing] (J0)

Stage 1

  • errors::verify_ast_passes_abi_cannot_be_coroutine_68: [missing] -> pass (J1)
  • errors::verify_ast_passes_abi_custom_safe_foreign_function_66: [missing] -> pass (J1)
  • errors::verify_ast_passes_abi_custom_safe_function_67: [missing] -> pass (J1)
  • errors::verify_ast_passes_abi_must_not_have_parameters_or_return_type_69: [missing] -> pass (J1)
  • errors::verify_ast_passes_abi_must_not_have_return_type_70: [missing] -> pass (J1)
  • errors::verify_ast_passes_assoc_const_without_body_10: pass -> [missing] (J1)
  • errors::verify_ast_passes_assoc_const_without_body_11: [missing] -> pass (J1)
  • errors::verify_ast_passes_async_fn_in_const_trait_or_trait_impl_1: pass -> [missing] (J1)
  • errors::verify_ast_passes_at_least_one_trait_40: [missing] -> pass (J1)
  • errors::verify_ast_passes_auto_generic_33: pass -> [missing] (J1)
  • errors::verify_ast_passes_auto_items_36: [missing] -> pass (J1)
  • errors::verify_ast_passes_c_variadic_bad_extern_28: pass -> [missing] (J1)
  • errors::verify_ast_passes_c_variadic_bad_naked_extern_30: [missing] -> pass (J1)
  • errors::verify_ast_passes_const_and_coroutine_51: pass -> [missing] (J1)
  • errors::verify_ast_passes_const_without_body_14: [missing] -> pass (J1)
  • errors::verify_ast_passes_constraint_on_negative_bound_58: pass -> [missing] (J1)
  • errors::verify_ast_passes_constraint_on_negative_bound_59: [missing] -> pass (J1)
  • errors::verify_ast_passes_coroutine_and_c_variadic_54: [missing] -> pass (J1)
  • errors::verify_ast_passes_extern_invalid_safety_16: pass -> [missing] (J1)
  • errors::verify_ast_passes_extern_item_ascii_25: pass -> [missing] (J1)
  • errors::verify_ast_passes_extern_types_cannot_22: [missing] -> pass (J1)
  • errors::verify_ast_passes_extern_without_abi_63: pass -> [missing] (J1)
  • errors::verify_ast_passes_extern_without_abi_64: [missing] -> pass (J1)
  • errors::verify_ast_passes_extern_without_abi_sugg_65: [missing] -> pass (J1)
  • errors::verify_ast_passes_fn_param_doc_comment_7: [missing] -> pass (J1)
  • errors::verify_ast_passes_fn_param_forbidden_attr_8: [missing] -> pass (J1)
  • errors::verify_ast_passes_fn_param_forbidden_self_8: pass -> [missing] (J1)
  • errors::verify_ast_passes_fn_param_too_many_4: pass -> [missing] (J1)
  • errors::verify_ast_passes_fn_ptr_invalid_safety_18: pass -> [missing] (J1)
  • errors::verify_ast_passes_forbidden_default_10: [missing] -> pass (J1)
  • errors::verify_ast_passes_generic_default_trailing_49: [missing] -> pass (J1)
  • errors::verify_ast_passes_incompatible_features_56: pass -> [missing] (J1)
  • errors::verify_ast_passes_item_invalid_safety_17: pass -> [missing] (J1)
  • errors::verify_ast_passes_item_invalid_safety_18: [missing] -> pass (J1)
  • errors::verify_ast_passes_item_underscore_31: [missing] -> pass (J1)
  • errors::verify_ast_passes_match_arm_with_no_body_61: [missing] -> pass (J1)
  • errors::verify_ast_passes_negative_bound_with_parenthetical_notation_59: pass -> [missing] (J1)
  • errors::verify_ast_passes_negative_bound_with_parenthetical_notation_60: [missing] -> pass (J1)
  • errors::verify_ast_passes_nested_impl_trait_39: [missing] -> pass (J1)
  • errors::verify_ast_passes_nested_lifetimes_50: [missing] -> pass (J1)
  • errors::verify_ast_passes_nomangle_ascii_31: pass -> [missing] (J1)
  • errors::verify_ast_passes_out_of_order_params_40: pass -> [missing] (J1)
  • errors::verify_ast_passes_pattern_in_fn_pointer_37: [missing] -> pass (J1)
  • errors::verify_ast_passes_pattern_in_foreign_54: pass -> [missing] (J1)
  • errors::verify_ast_passes_static_without_body_15: [missing] -> pass (J1)
  • errors::verify_ast_passes_trait_fn_const_1: [missing] -> pass (J1)
  • errors::verify_ast_passes_trait_object_single_bound_37: pass -> [missing] (J1)
  • errors::verify_ast_passes_unsafe_item_43: pass -> [missing] (J1)
  • errors::verify_ast_passes_unsafe_static_19: pass -> [missing] (J1)
  • errors::verify_ast_passes_unsafe_static_20: [missing] -> pass (J1)
  • errors::verify_ast_passes_where_clause_after_type_alias_48: [missing] -> pass (J1)

Stage 2

  • [ui] tests/ui/traits/const-traits/const-impl-inherent-bounds.rs: [missing] -> pass (J2)
  • [ui] tests/ui/traits/const-traits/const-impl-inherent.rs: [missing] -> pass (J2)

(and 196 additional test diffs)

Additionally, 14 doctest diffs were found. These are ignored, as they are noisy.

Job group index

Test dashboard

Run

cargo run --manifest-path src/ci/citool/Cargo.toml -- \
    test-dashboard 6159a44067ebce42b38f062cc7df267a1348e092 --output-dir test-dashboard

And then open test-dashboard/index.html in your browser to see an overview of all executed tests.

Job duration changes

  1. pr-check-1: 1673.2s -> 2060.2s (+23.1%)
  2. x86_64-gnu-llvm-20: 2451.0s -> 2839.6s (+15.9%)
  3. x86_64-rust-for-linux: 2608.9s -> 2989.7s (+14.6%)
  4. x86_64-gnu-llvm-20-1: 3160.3s -> 3586.9s (+13.5%)
  5. x86_64-gnu-llvm-20-2: 5631.0s -> 6362.6s (+13.0%)
  6. armhf-gnu: 4934.7s -> 5565.8s (+12.8%)
  7. dist-i686-msvc: 8171.5s -> 9211.4s (+12.7%)
  8. x86_64-gnu-gcc: 3079.5s -> 3466.2s (+12.6%)
  9. x86_64-gnu-tools: 3288.1s -> 3665.8s (+11.5%)
  10. i686-gnu-2: 5606.1s -> 6237.1s (+11.3%)
How to interpret the job duration changes?

Job durations can vary a lot, based on the actual runner instance
that executed the job, system noise, invalidated caches, etc. The table above is provided
mostly for t-infra members, for simpler debugging of potential CI slow-downs.

@rust-timer
Copy link
Collaborator

Finished benchmarking commit (6159a44): comparison URL.

Overall result: ❌✅ regressions and improvements - please read the text below

Our benchmarks found a performance regression caused by this PR.
This might be an actual regression, but it can also be just noise.

Next Steps:

  • If the regression was expected or you think it can be justified,
    please write a comment with sufficient written justification, and add
    @rustbot label: +perf-regression-triaged to it, to mark the regression as triaged.
  • If you think that you know of a way to resolve the regression, try to create
    a new PR with a fix for the regression.
  • If you do not understand the regression or you think that it is just noise,
    you can ask the @rust-lang/wg-compiler-performance working group for help (members of this group
    were already notified of this PR).

@rustbot label: +perf-regression
cc @rust-lang/wg-compiler-performance

Instruction count

Our most reliable metric. Used to determine the overall result above. However, even this metric can be noisy.

mean range count
Regressions ❌
(primary)
2.9% [2.9%, 2.9%] 1
Regressions ❌
(secondary)
- - 0
Improvements ✅
(primary)
-0.3% [-0.3%, -0.3%] 1
Improvements ✅
(secondary)
-0.5% [-0.9%, -0.2%] 9
All ❌✅ (primary) 1.3% [-0.3%, 2.9%] 2

Max RSS (memory usage)

Results (primary 3.0%, secondary -0.5%)

A less reliable metric. May be of interest, but not used to determine the overall result above.

mean range count
Regressions ❌
(primary)
3.0% [3.0%, 3.0%] 1
Regressions ❌
(secondary)
0.7% [0.7%, 0.7%] 3
Improvements ✅
(primary)
- - 0
Improvements ✅
(secondary)
-4.2% [-4.2%, -4.2%] 1
All ❌✅ (primary) 3.0% [3.0%, 3.0%] 1

Cycles

Results (primary 2.7%, secondary -1.3%)

A less reliable metric. May be of interest, but not used to determine the overall result above.

mean range count
Regressions ❌
(primary)
2.7% [2.7%, 2.7%] 1
Regressions ❌
(secondary)
3.4% [3.0%, 3.8%] 2
Improvements ✅
(primary)
- - 0
Improvements ✅
(secondary)
-3.2% [-4.0%, -2.7%] 5
All ❌✅ (primary) 2.7% [2.7%, 2.7%] 1

Binary size

Results (primary 1.1%)

A less reliable metric. May be of interest, but not used to determine the overall result above.

mean range count
Regressions ❌
(primary)
1.1% [1.1%, 1.1%] 1
Regressions ❌
(secondary)
- - 0
Improvements ✅
(primary)
- - 0
Improvements ✅
(secondary)
- - 0
All ❌✅ (primary) 1.1% [1.1%, 1.1%] 1

Bootstrap: 474.558s -> 473.45s (-0.23%)
Artifact size: 388.75 MiB -> 388.78 MiB (0.01%)

@rustbot rustbot added the perf-regression Performance regression. label Nov 19, 2025
bors added a commit that referenced this pull request Nov 19, 2025
Avoid encoding non-constness or non-asyncness in metadata

r? `@fee1-dead`

Let's see if we can get any benefit (even just metadata size) from not encoding the common case.

Inspired by #148434 (comment)
@panstromek
Copy link
Contributor

perf triage:

clap_derive noise.

@rustbot label: +perf-regression-triaged

@rustbot rustbot added the perf-regression-triaged The performance regression has been triaged. label Nov 19, 2025
@oli-obk oli-obk deleted the inherent-const-impl branch November 19, 2025 13:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

F-const_trait_impl `#![feature(const_trait_impl)]` merged-by-bors This PR was explicitly merged by bors. perf-regression Performance regression. perf-regression-triaged The performance regression has been triaged. PG-const-traits Project group: Const traits S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-clippy Relevant to the Clippy team. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-rustfmt Relevant to the rustfmt team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

9 participants