-
Notifications
You must be signed in to change notification settings - Fork 0
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
Conversation
@@ -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, |
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.
this would need changing the doc string
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 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
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 mean, I feel like it would need to be renamed in that case
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.
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) = |
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'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, |
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.
Can we split this function into two? Compute 2229_drop_migrations and 2229_auto_trait_migrations
src/test/ui/closures/2229_closure_analysis/migrations/auto_traits.fixed
Outdated
Show resolved
Hide resolved
src/test/ui/closures/2229_closure_analysis/migrations/mir_calls_to_shims.fixed
Show resolved
Hide resolved
&self, | ||
set_reasons: FxHashSet<&str> | ||
) -> String { | ||
let mut reasons = String::new(); |
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.
you can create a vector, keep pushing reason
then you can call x.join(", ")
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.
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 { |
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.
maybe create a vector of tuple (trait_def_id, reason_string) and then iterator over them?
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.
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 |
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.
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>, |
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.
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 🙃
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.
Nvm i see why you're using hashset. I'm dumb
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.
Tis ok, I figured out how to use vector instead without have dups
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.
@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 |
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 can't figure out how to trigger the 'Sync' error here. Are we sure there should be an issue with AssertUnwindSafe
?
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.
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.
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.
It was an example used in one of the Issues. I was under the impression this should trigger an error? Should it not?
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.
not for the ysnc trait, but for the AssertUnwindSafe trati
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.
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> |
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 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() { |
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 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") |
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.
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`", |
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.
Also I'mm not sure if "Sync trait affected for closure" is the best wording
cdb2fe6
to
25f3d74
Compare
Combine all 2229 migrations under one flag name
This PR adds a new migration fixup to handle semantics change for traits when using
capture_disjoint_fields
featureCloses rust-lang/project-rfc-2229#29
Closes rust-lang/project-rfc-2229#28