-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
Replace #[default_method_body_is_const]
with #[const_trait]
#96964
Conversation
Hey! It looks like you've submitted a new PR for the library teams! If this PR contains changes to any Examples of
|
(rust-highfive has picked a reviewer for you, use r? to override) |
☔ The latest upstream changes (presumably #95562) made this pull request unmergeable. Please resolve the merge conflicts. |
(Please do not r? me because I have written parts of this PR.) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Part of me would like the syntax to require const fn
for the default methods, as it's not immediately clear that it's the case with this change. But I understand that the syntax/attributes is largely in flux, so that's not a deal-breaker for me.
Overall, the PR looks good. Just some minor nits.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
☔ The latest upstream changes (presumably #96825) made this pull request unmergeable. Please resolve the merge conflicts. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM pending rebase.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
r=me, left a few comments (or ignore them, that's fine too)
// At this point, it is only legal when the caller is in a trait | ||
// marked with #[const_trait], and the callee is in the same trait. | ||
let mut nonconst_call_permission = false; | ||
if let Some(callee_trait) = tcx.trait_of_item(callee) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wish if
chains could be booleans, sigh
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure what this means :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sorry, meant let
chains. just don't like how this has to be a mutable assignment lol. not an actionable comment.
…ait can be treated as `const`
…esugar to a method in a new impl block
Co-authored-by: fee1-dead <[email protected]>
@bors r=compiler-errors |
📌 Commit 2f96fbe has been approved by |
☀️ Test successful - checks-actions |
Finished benchmarking commit (5c780b9): comparison url. Instruction count
Max RSS (memory usage)Results
CyclesResults
If you disagree with this performance assessment, please file an issue in rust-lang/rustc-perf. Next Steps: If you can justify the regressions found in this perf run, please indicate this with @rustbot label: +perf-regression Footnotes |
@rustbot label: +perf-regression-triaged |
let trait_def_id = imp.of_trait.as_ref()?.trait_def_id()?; | ||
let ancestors = tcx | ||
.trait_def(trait_def_id) | ||
.ancestors(tcx, item.def_id.to_def_id()) | ||
.ok()?; | ||
let mut to_implement = Vec::new(); | ||
|
||
for trait_item in tcx.associated_items(trait_def_id).in_definition_order() | ||
{ | ||
if let ty::AssocItem { | ||
kind: ty::AssocKind::Fn, | ||
defaultness, | ||
def_id: trait_item_id, | ||
.. | ||
} = *trait_item | ||
{ | ||
// we can ignore functions that do not have default bodies: | ||
// if those are unimplemented it will be caught by typeck. | ||
if !defaultness.has_value() | ||
|| tcx | ||
.has_attr(trait_item_id, sym::default_method_body_is_const) | ||
{ | ||
continue; | ||
} | ||
|
||
let is_implemented = ancestors | ||
.leaf_def(tcx, trait_item_id) | ||
.map(|node_item| !node_item.defining_node.is_from_trait()) | ||
.unwrap_or(false); | ||
|
||
if !is_implemented { | ||
to_implement.push(trait_item_id); | ||
} | ||
} | ||
} | ||
|
||
// all nonconst trait functions (not marked with #[default_method_body_is_const]) | ||
// must be implemented | ||
if !to_implement.is_empty() { | ||
let not_implemented = to_implement | ||
.into_iter() | ||
.map(|did| tcx.item_name(did).to_string()) | ||
.collect::<Vec<_>>() | ||
.join("`, `"); | ||
tcx | ||
.sess | ||
.struct_span_err( | ||
item.span, | ||
"const trait implementations may not use non-const default functions", | ||
) | ||
.note(&format!("`{}` not implemented", not_implemented)) | ||
.emit(); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we forgot to actually forbid impl const
on non #[const_trait]
which would be here
pulled out of #96077
related issues: #67792 and #92158
cc @fee1-dead
This is groundwork to only allowing
impl const Trait
for traits that are marked with#[const_trait]
. This is necessary to prevent adding a new default method from becoming a breaking change (as it could be a non-const fn).