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

Introduce TypeVisitor::BreakTy #78779

Merged
merged 9 commits into from
Nov 17, 2020
Merged

Conversation

LeSeulArtichaut
Copy link
Contributor

@LeSeulArtichaut LeSeulArtichaut commented Nov 5, 2020

@LeSeulArtichaut LeSeulArtichaut marked this pull request as draft November 5, 2020 17:15
@LeSeulArtichaut LeSeulArtichaut added C-cleanup Category: PRs that clean code up or issues documenting cleanup. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Nov 5, 2020
@@ -227,8 +217,7 @@ impl<'a, 'tcx> TypeVisitor<'tcx> for Search<'a, 'tcx> {

if !self.type_marked_structural(ty) {
debug!("Search found ty: {:?}", ty);
self.found = Some(NonStructuralMatchTy::Adt(&adt_def));
return ControlFlow::BREAK;
return ControlFlow::Break(NonStructuralMatchTy::Adt(&adt_def));
Copy link
Member

Choose a reason for hiding this comment

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

❤️

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, I find the code so much cleaner this way 😄

@@ -73,7 +73,7 @@ pub trait TypeFoldable<'tcx>: fmt::Debug + Clone {
}

fn has_type_flags(&self, flags: TypeFlags) -> bool {
self.visit_with(&mut HasTypeFlagsVisitor { flags }).is_break()
self.visit_with(&mut HasTypeFlagsVisitor { flags }).break_value() == Some(FoundFlags)
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't see the advantage of using a type other than () for the break in this case.

Copy link
Contributor Author

@LeSeulArtichaut LeSeulArtichaut Nov 6, 2020

Choose a reason for hiding this comment

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

(This was #78182 (comment))

Copy link
Contributor

Choose a reason for hiding this comment

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

Oh right, I remember that comment. @lcnr can you elaborate on the motivation? We should encode it in documentation/comments

Copy link
Contributor

Choose a reason for hiding this comment

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

Using a ZST we explicitly document the reasons we stop visiting and the reason we check if we terminated early.

While it isn't too relevant, it makes it easier to prevent bugs like stopping early because of a different reason and forgetting to update a call site. I also feel like using a ZST here has a very low cost and removes some questions on why we are using is_break and under which conditions we want to stop visiting.

Don't really care too much about this though

Copy link
Contributor

Choose a reason for hiding this comment

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

I have nothing to argue against that 😆

If we can manage to remove is_break in that case (when all visitors have been migrated), then that would enforce this by there not being a way around it.

Copy link
Contributor

Choose a reason for hiding this comment

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

Oh... now that I finished reading the PR, I think we should also stop having () as a default for BreakTy and require the user to specify one (or use ! as the default?)

Copy link
Contributor

@lcnr lcnr Nov 9, 2020

Choose a reason for hiding this comment

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

using ! as a default would be interesting 🤔 can't be misused and makes people notice the possibility

Copy link
Contributor Author

Choose a reason for hiding this comment

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

65cdc21 🙂

compiler/rustc_middle/src/ty/fold.rs Show resolved Hide resolved
@LeSeulArtichaut LeSeulArtichaut marked this pull request as ready for review November 6, 2020 18:14
@LeSeulArtichaut LeSeulArtichaut added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Nov 6, 2020
@LeSeulArtichaut
Copy link
Contributor Author

r? @oli-obk

@LeSeulArtichaut LeSeulArtichaut added the S-waiting-on-fcp Status: PR is in FCP and is awaiting for FCP to complete. label Nov 6, 2020
@@ -964,14 +993,16 @@ impl LateBoundRegionsCollector {
}

impl<'tcx> TypeVisitor<'tcx> for LateBoundRegionsCollector {
fn visit_binder<T: TypeFoldable<'tcx>>(&mut self, t: &Binder<T>) -> ControlFlow<()> {
type BreakTy = !;
Copy link
Contributor

Choose a reason for hiding this comment

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

debug!("Search visiting ty: {:?}", ty);

let (adt_def, substs) = match *ty.kind() {
ty::Adt(adt_def, substs) => (adt_def, substs),
ty::Param(_) => {
self.found = Some(NonStructuralMatchTy::Param);
return ControlFlow::BREAK;
return ControlFlow::Break(NonStructuralMatchTy::Param);
Copy link
Contributor

Choose a reason for hiding this comment

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

this is such a huge improvement to the implementation which still used bools ❤️ thank you for implementing all of this

debug!("check_opaque_for_inheriting_lifetimes: (visit_ty) t={:?}", t);
if t != self.opaque_identity_ty && t.super_visit_with(self).is_break() {
self.ty = Some(t);
return ControlFlow::BREAK;
return ControlFlow::Break(Some(t));
Copy link
Contributor

Choose a reason for hiding this comment

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

It looks to me like there are actually 2 visitors merged into 1 here.

The first one finds all opaque types and the second one then searches for inherited parent lifetimes, might make sense to try and split this. Not sure if you want to do this in one PR

Copy link
Contributor

Choose a reason for hiding this comment

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

debug!(
"check_opaque_for_inheriting_lifetimes: prohibit_opaque={:?}, visitor={:?}",
prohibit_opaque, visitor
);

if prohibit_opaque {
if let Some(ty) = prohibit_opaque.break_value() {
Copy link
Contributor

Choose a reason for hiding this comment

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

Can ty.unwrap() fail here? I would expect this to not be the case. Might be missing something though.

Maybe if we have a PredicateAtom::RegionOutlives 🤔

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Copy link
Contributor

@lcnr lcnr Nov 6, 2020

Choose a reason for hiding this comment

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

yeah, but this only ends up returning None if we aren't inside of a type, as we would otherwise return Some(ty) there

edit: this may happen if the predicate is an outlives predicate though I don't know if they are possible for opaque types, don't have the capacity to look into this myself atm

Copy link
Contributor

@lcnr lcnr left a comment

Choose a reason for hiding this comment

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

I personally would like to push a bit more to using ZST here and pretty much never use (). So I wouldn't add a associated type default here.

afaict @oli-obk has a different opinion so I am also fine with merging this as is.

@LeSeulArtichaut
Copy link
Contributor Author

We could change things in follow-up PRs. I made every change in a separate commit so I can easily drop some.

@LeSeulArtichaut LeSeulArtichaut force-pushed the ty-visitor-return branch 2 times, most recently from df22308 to a815e9e Compare November 6, 2020 22:46
fn visit_ty(&mut self, t: Ty<'_>) -> ControlFlow<Self::BreakTy> {
debug!(
"HasTypeFlagsVisitor: t={:?} t.flags={:?} self.flags={:?}",
t,
t.flags(),
self.flags
);
if t.flags().intersects(self.flags) { ControlFlow::BREAK } else { ControlFlow::CONTINUE }
if t.flags().intersects(self.flags) {
Copy link
Contributor

@oli-obk oli-obk Nov 9, 2020

Choose a reason for hiding this comment

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

Maybe create a self.check_flags method that handles this intersects call and the if-condition?

@oli-obk
Copy link
Contributor

oli-obk commented Nov 15, 2020

r=me,lcnr with the dead function removed

@LeSeulArtichaut
Copy link
Contributor Author

Done.
Note: rust-lang/compiler-team#383 still has two more hours in FCP to be accepted, but I haven't seen any objections anywhere so by the time this lands the MCP should be accepted.

@oli-obk
Copy link
Contributor

oli-obk commented Nov 15, 2020

@bors r+

yea, I think we can safely send it to bors, too

@bors
Copy link
Contributor

bors commented Nov 15, 2020

📌 Commit f6e6a15 has been approved by oli-obk

@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-review Status: Awaiting review from the assignee but also interested parties. labels Nov 15, 2020
@LeSeulArtichaut
Copy link
Contributor Author

Should this be rollup=never as a medium-sized refractor? (I'm still trying to understand what deserves rollup=never besides perf-sensitive changes)

@oli-obk
Copy link
Contributor

oli-obk commented Nov 15, 2020

for non-perf non prioritized things that probably conflict with a bunch of things we have

@bors rollup=iffy

@LeSeulArtichaut LeSeulArtichaut removed the S-waiting-on-fcp Status: PR is in FCP and is awaiting for FCP to complete. label Nov 15, 2020
@bors
Copy link
Contributor

bors commented Nov 16, 2020

⌛ Testing commit f6e6a15 with merge aacb816092fb150a8459de3135f62d6199fedf62...

@bors
Copy link
Contributor

bors commented Nov 16, 2020

💥 Test timed out

@bors bors added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. labels Nov 16, 2020
@oli-obk
Copy link
Contributor

oli-obk commented Nov 16, 2020

@bors retry

@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-review Status: Awaiting review from the assignee but also interested parties. labels Nov 16, 2020
Dylan-DPC-zz pushed a commit to Dylan-DPC-zz/rust that referenced this pull request Nov 17, 2020
…r=oli-obk

Introduce `TypeVisitor::BreakTy`

Implements MCP rust-lang/compiler-team#383.
r? `@ghost`
cc `@lcnr` `@oli-obk`

~~Blocked on FCP in rust-lang/compiler-team#383.~~
@bors
Copy link
Contributor

bors commented Nov 17, 2020

⌛ Testing commit f6e6a15 with merge e0ef0fc...

@bors
Copy link
Contributor

bors commented Nov 17, 2020

☀️ Test successful - checks-actions
Approved by: oli-obk
Pushing e0ef0fc to master...

@bors bors added the merged-by-bors This PR was explicitly merged by bors. label Nov 17, 2020
@bors bors merged commit e0ef0fc into rust-lang:master Nov 17, 2020
@rustbot rustbot added this to the 1.50.0 milestone Nov 17, 2020
@LeSeulArtichaut LeSeulArtichaut deleted the ty-visitor-return branch November 17, 2020 14:54
flip1995 pushed a commit to flip1995/rust that referenced this pull request Nov 20, 2020
…oli-obk

Introduce `TypeVisitor::BreakTy`

Implements MCP rust-lang/compiler-team#383.
r? `@ghost`
cc `@lcnr` `@oli-obk`

~~Blocked on FCP in rust-lang/compiler-team#383.~~
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-cleanup Category: PRs that clean code up or issues documenting cleanup. merged-by-bors This PR was explicitly merged by bors. S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants