Skip to content

Handle auto trait migration #52

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

Merged
merged 4 commits into from
May 12, 2021
Merged

Handle auto trait migration #52

merged 4 commits into from
May 12, 2021

Conversation

roxelo
Copy link
Member

@roxelo roxelo commented Apr 8, 2021

This PR adds a new migration fixup to handle semantics change for traits when using capture_disjoint_fields feature

Closes rust-lang/project-rfc-2229#29
Closes rust-lang/project-rfc-2229#28

@@ -542,19 +606,57 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
closure_span: Span,
closure_clause: hir::CaptureBy,
min_captures: Option<&ty::RootVariableMinCaptureList<'tcx>>,
) -> Vec<hir::HirId> {
should_do_drop_migration: bool,
Copy link
Member

Choose a reason for hiding this comment

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

this would need changing the doc string

Copy link
Member

Choose a reason for hiding this comment

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

I would keep the original funciton as is and create a new one. They don't share too much code together, and it just requires maintaining cotext of the conditionals while reading the code

Copy link
Member Author

Choose a reason for hiding this comment

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

I mean, I feel like it would need to be renamed in that case

Copy link
Member

Choose a reason for hiding this comment

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

Can we split this function into two? Compute 2229_drop_migrations and 2229_auto_trait_migrations

@@ -525,6 +541,54 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
},
);
}

if !need_traits_migrations.is_empty() {
let (migration_string, migrated_variables_concat) =
Copy link
Member

Choose a reason for hiding this comment

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

I'd create a function or clousre that does most of this, the two codeblocks are basically the same with the paramters being the lint and the associated messages

@@ -542,19 +606,57 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
closure_span: Span,
closure_clause: hir::CaptureBy,
min_captures: Option<&ty::RootVariableMinCaptureList<'tcx>>,
) -> Vec<hir::HirId> {
should_do_drop_migration: bool,
Copy link
Member

Choose a reason for hiding this comment

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

Can we split this function into two? Compute 2229_drop_migrations and 2229_auto_trait_migrations

&self,
set_reasons: FxHashSet<&str>
) -> String {
let mut reasons = String::new();
Copy link
Member

Choose a reason for hiding this comment

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

you can create a vector, keep pushing reason
then you can call x.join(", ")

Copy link
Member Author

Choose a reason for hiding this comment

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

Doesn't work well if we want to include the words "trait implementation" too

let cause = ObligationCause::misc(self.tcx.hir().span(var_hir_id), self.body_id);

// <ty as Clone>
let clone_trait_ref = TraitRef {
Copy link
Member

Choose a reason for hiding this comment

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

maybe create a vector of tuple (trait_def_id, reason_string) and then iterator over them?

Copy link
Member Author

Choose a reason for hiding this comment

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

Don't think it would help a lot, maybe creating a function instead? I may come back to this once I am in a more final version

return None
};

let is_not_completely_captured = !root_var_min_capture_list
Copy link
Member

Choose a reason for hiding this comment

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

what we really need to check is that if path A implement the trait and then any of the captured paths don't implement the trait

}

/// Return a two string tuple (s1, s2)
/// - s1: Line of code that is needed for the migration: eg: `let _ = (&x, ...)`.
/// - s2: Comma separated names of the variables being migrated.
fn migration_suggestion_for_2229(
tcx: TyCtxt<'_>,
need_migrations: &Vec<hir::HirId>,
need_migrations: &FxHashSet<hir::HirId>,
Copy link
Member

Choose a reason for hiding this comment

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

we should keep this a vector; we want to preserve order. otherwise things might get dropped in a different ordered.

Though we have a ticket to fix it overall, so might not be too bad 🙃

Copy link
Member

Choose a reason for hiding this comment

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

Nvm i see why you're using hashset. I'm dumb

Copy link
Member Author

Choose a reason for hiding this comment

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

Tis ok, I figured out how to use vector instead without have dups

@arora-aman arora-aman self-assigned this Apr 20, 2021
Copy link
Member Author

@roxelo roxelo left a comment

Choose a reason for hiding this comment

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

@arora-aman Started addressing some of your comments from last night. Still having a few issues here. If you have any ideas, let me know. I'll do a cleanup later and fix any formatting issues

let f = panic::AssertUnwindSafe(f);
let result = panic::catch_unwind(move || {
//~^ ERROR: 'Sync' trait implementation affected for closure because of `capture_disjoint_fields`
//~| HELP: add a dummy let to cause `f` to be fully captured
f.0()
f.0.0
Copy link
Member Author

Choose a reason for hiding this comment

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

I can't figure out how to trigger the 'Sync' error here. Are we sure there should be an issue with AssertUnwindSafe?

Copy link
Member

Choose a reason for hiding this comment

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

why would sync trigger here? Also all objects are by default Send and Sync unles they contain something that is not Send/Sync, making Foo and i32 Send/Sync.

Copy link
Member Author

Choose a reason for hiding this comment

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

It was an example used in one of the Issues. I was under the impression this should trigger an error? Should it not?

Copy link
Member

Choose a reason for hiding this comment

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

not for the ysnc trait, but for the AssertUnwindSafe trati

Copy link
Member Author

Choose a reason for hiding this comment

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

Ohh, so I should also check for this one?

} else {
// The upvar is mentioned within the closure but no path starting from it is
// used.
// <ty as Sync>
Copy link
Member Author

Choose a reason for hiding this comment

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

I can't figure out how we can check for Send trait? Maybe I am missing where it is suppose to be??

// Check whether catpured fields also implement the trait
let mut temp_reasons = FxHashSet::default();

for capture in root_var_min_capture_list.iter() {
Copy link
Member

Choose a reason for hiding this comment

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

I think this function can use some form of helper, because I see a quite a fair bit of repetition.

Something like

// return true if the variables needs to be migrated
fn 2229_trait_migration_helper(&self, var_hir_id, trait_def_id) -> bool {
 
      // checks that if the trait is satisifed by root varirable; if not return false
     // check if the trait is not satisfied by an of the captured paths, if so return true. 
}

One thing to check with niko would be if we want to report why a paricular root variable is being migrated, i.e. store (variable, reason) pairs.

reasons = format!("{}'Unpin'", reasons);
}

if set_reasons.contains("Clone")
Copy link
Member

Choose a reason for hiding this comment

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

you can just check for is reasons is not empty

closure_hir_id,
span,
|lint| {
let mut diagnostics_builder = lint.build(
"drop order affected for closure because of `capture_disjoint_fields`",
format!(
"{} affected for closure because of `capture_disjoint_fields`",
Copy link
Member

Choose a reason for hiding this comment

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

Also I'mm not sure if "Sync trait affected for closure" is the best wording

@roxelo roxelo force-pushed the rox-auto-trait branch 2 times, most recently from cdb2fe6 to 25f3d74 Compare April 30, 2021 00:18
@roxelo roxelo force-pushed the rox-auto-trait branch from 25f3d74 to ad5e18d Compare May 6, 2021 18:58
@sexxi-bot sexxi-bot merged commit 28e2b29 into master May 12, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Auto traits with closures Possible closure not being Clone anymore
3 participants