Skip to content
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

Let qualify_min_const_fn deal with drop terminators #12681

Merged
merged 3 commits into from
Jun 11, 2024

Conversation

y21
Copy link
Member

@y21 y21 commented Apr 16, 2024

Fixes #12677

The method_accepts_droppable check that was there seemed overly conservative.

Returns true if any of the method parameters is a type that implements Drop.
The method can't be made const then, because drop can't be const-evaluated.

Accepting parameters that implement Drop should still be fine as long as the parameter isn't actually dropped, as is the case in the linked issue where the droppable is moved into the return place. This more accurate analysis ("is there a drop terminator") is already done by qualify_min_const_fn here, so I don't think this additional check is really necessary?

Fixing the other, second case in the linked issue was only slightly more involved, since Vec::new() is a function call that has the ability to panic, so there must be a drop() terminator for cleanup, however we should be able to freely ignore that. Const checking ignores cleanup blocks, so we should, too?

r? @Jarcho


changelog: [missing_const_for_fn]: continue linting on fns with parameters implementing Drop if they're not actually dropped

@rustbot rustbot added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties label Apr 16, 2024
@y21
Copy link
Member Author

y21 commented Apr 16, 2024

I do wonder what

if let Err((span, err)) = is_min_const_fn(cx.tcx, mir, &self.msrv) {
if cx.tcx.is_const_fn_raw(def_id.to_def_id()) {
cx.tcx.dcx().span_err(span, err);
}
} else {
is for... That seems like dead code essentially. We are early-returning if already_const before this, so I don't see how is_const_fn_raw() could be true.

@bors
Copy link
Collaborator

bors commented May 15, 2024

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

@Jarcho
Copy link
Contributor

Jarcho commented Jun 5, 2024

The whole error returning part of is_min_const_fn is pointless since it was moved into clippy. Feel free to remove it and r=me either way.

@y21
Copy link
Member Author

y21 commented Jun 6, 2024

I assume you mean specifically is_min_const_fn could just return a bool, right? Returning a result in the private fns would still be useful since it allows using ? everywhere (could be a ZST error type if we never really use it but not sure if changing that is worth it)

@Jarcho
Copy link
Contributor

Jarcho commented Jun 6, 2024

Replacing the loops with Iterator::all would be just as simple. I see no need to hold this fix up on such a change, unless you want to do it right now.

@y21
Copy link
Member Author

y21 commented Jun 7, 2024

I was trying to clean some of the error stuff up but found that the error reason strings seemed useful (even just for documentation purposes, maybe they should be comments), so it felt a bit bad to remove that. So I just left it for now and just removed the unused error handling in missing_const_for_fn (last commit), though it does make the errors redundant as you said. I can still try to remove them if you want

Replacing the loops with Iterator::all would be just as simple.

Also I must be imagining this differently because it doesn't seem as simple, or at least not as nice as simply changing the error type in McfResult to some ZST struct (which would allow us to just continue using ? like it currently does, and would lose when changing to bool)? Do you mean having a large chain of && in the top level is_min_const_fn which calls all the check_* fns, that all still return McfResult?

@Jarcho
Copy link
Contributor

Jarcho commented Jun 8, 2024

The lack of? isn't a problem when working with large boolean expressions like this does. foo()?; bar()? is foo() && bar(). for item in foo { bar(item)? } is foo().iter().all(|item| bar(item)). for item in foo { if let Some(item) = item { bar(item)? } } is foo().iter().filter_map(|item| item).all(|item| bar(item)).

It will be less work to just use a unit error type, but that's only because it's already written. Again, I don't really care which way you go here. It's unrelated to the bug being fixed.

@Jarcho
Copy link
Contributor

Jarcho commented Jun 11, 2024

@bors r+

I'm going ahead and merging this since it's fine as is and fixes a bug. Any extra cleanup can be done with another PR.

@bors
Copy link
Collaborator

bors commented Jun 11, 2024

📌 Commit c3d3a3f has been approved by Jarcho

It is now in the queue for this repository.

@bors
Copy link
Collaborator

bors commented Jun 11, 2024

⌛ Testing commit c3d3a3f with merge 38d12a9...

@bors
Copy link
Collaborator

bors commented Jun 11, 2024

☀️ Test successful - checks-action_dev_test, checks-action_remark_test, checks-action_test
Approved by: Jarcho
Pushing 38d12a9 to master...

@bors bors merged commit 38d12a9 into rust-lang:master Jun 11, 2024
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-review Status: Awaiting review from the assignee but also interested parties
Projects
None yet
Development

Successfully merging this pull request may close these issues.

missing_const_for_fn misses some cases with generics involved
4 participants