-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
[WIP] Ergonomic ref counting #134797
base: master
Are you sure you want to change the base?
[WIP] Ergonomic ref counting #134797
Conversation
e4e8ad3
to
b003b20
Compare
This comment has been minimized.
This comment has been minimized.
b003b20
to
94d4dde
Compare
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
42e6956
to
0aaedb8
Compare
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
f9a2abe
to
0c29a0b
Compare
This comment has been minimized.
This comment has been minimized.
0c29a0b
to
b82e779
Compare
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.
Very close! First round of feedback.
/// Desugar `<expr>.use` into: | ||
/// ```ignore (pseudo-rust) | ||
/// <expr>.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.
This comment is out of date
/// ``` | ||
fn lower_expr_use(&mut self, use_kw_span: Span, expr: &Expr) -> hir::ExprKind<'hir> { | ||
let expr = self.lower_expr(expr); | ||
let span = self.mark_span_with_reason(DesugaringKind::Use, use_kw_span, None); |
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 don't think we want this DesugaringKind
anymore
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 was taking a quick look at this, this is used for diagnostic purposes, see for instance https://github.com/spastorino/rust/blob/b82e779259706ceb63fbd38fa5c9d8b9b632149a/compiler/rustc_borrowck/src/diagnostics/mod.rs#L1200-L1207
Do you meant to say that .use
doesn't move so this error is not important. Also my code doesn't completely handles the DesugaringKind, so or I should remove if this error shouldn't happen or I should do the actual handling of it :).
let place = unpack!(block = this.as_place(block, expr)); | ||
let ty = place.ty(&this.local_decls, this.tcx).ty; | ||
|
||
let success = this.cfg.start_new_block(); |
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 know this is going to change in future commits, but it needs a comment. Just something like
// Convert `expr.use` to a call like `Clone::clone(&expr)`
would go a long way
@@ -1331,6 +1332,12 @@ impl<'a> Parser<'a> { | |||
return Ok(self.mk_await_expr(self_arg, lo)); | |||
} | |||
|
|||
if self.eat_keyword(exp!(Use)) { | |||
let use_span = self.prev_token.span; | |||
self.psess.gated_spans.gate(sym::ergonomic_clones, use_span); |
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.
Is it normal to gate in the parser like this?
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.
Looks like it is, I am not sure what's most common
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.
From what I've seen in code it is and this is what @compiler-errors what asking me to do in a previous review. Can you confirm Michael?.
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 only is it "normal", it's literally imperative to gate in the parser to make sure that we don't accidentally stabilize the syntax in cfg'd code. Please make sure that there is a test that validates that this still gives an error when the code has #[cfg(any())]
.
@@ -1175,6 +1176,7 @@ impl DesugaringKind { | |||
DesugaringKind::CondTemporary => "`if` or `while` condition", | |||
DesugaringKind::Async => "`async` block or function", | |||
DesugaringKind::Await => "`await` expression", | |||
DesugaringKind::Use => "`use` expression", |
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 don't think we need this
@@ -1685,10 +1687,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { | |||
// | |||
// If the data will be moved out of this place, then the place will be truncated | |||
// at the first Deref in `adjust_for_move_closure` and then moved into the closure. |
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 you can extend this comment with the example I wrote in Zulip? I think it would help future readers.
@@ -367,6 +367,10 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx | |||
self.consume_exprs(args)?; | |||
} | |||
|
|||
hir::ExprKind::Use(expr, _) => { | |||
self.consume_expr(expr)?; |
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.
Hmm-- I just realized, this is.... not necessarily correct. Not necessarily wrong either. This says that expr
will be moved, but the true behavior is that expr
will be moved unless it implements UseCloned
. So this should be adjusted later on to take that into account.
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.
Should we do something like consume_copy_or_borrow
? if UseCloned
borrow, if copy Copy and move otherwise.
@@ -2339,8 +2357,10 @@ fn determine_capture_info( | |||
} | |||
} else { | |||
// We select the CaptureKind which ranks higher based the following priority order: | |||
// ByValue > MutBorrow > UniqueImmBorrow > ImmBorrow | |||
// ByUse > ByValue > MutBorrow > UniqueImmBorrow > ImmBorrow |
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.
Hmm, the ordering of ByUse
and ByValue
seems unclear to me, but I also expect that you never see them together? Maybe we should say (ty::UpvarCapture::ByUse, ty::UpvarCapture::ByMove) => bug!
(and vice versa) instead. -- I'd probably change the code here to not use _
but explicitly say (ByValue, ByRef(_)) => lhs
, etc.
Rvalue::Use(Operand::Copy(place)), | ||
); | ||
block.unit() | ||
} else if this.infcx.type_is_use_cloned_modulo_regions(this.param_env, ty) { |
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 same logic needs to go into the ExprUseVisitor
-- note that consume_expr
I think already tests whether the expression is "copy" or not, so that is covered
#[cfg_attr(not(bootstrap), lang = "use_cloned")] | ||
#[rustc_diagnostic_item = "UseCloned"] | ||
#[rustc_trivial_field_reads] | ||
pub trait UseCloned: 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.
should be "marker"
I've pushed some tests and I've found some parsing errors, a diagnostic ICE and another issue that needs handling during borrowck. CI is going to be red but is fine as this is not yet done. |
The job Click to see the possible cause of the failure (guessed by this bot)
|
Opening this now so @nikomatsakis can start taking a look at it. Going to write a proper description when the PR is done.
For this first version I'd need to:
For following versions we need to implement optimizations, copy optimization post monomorphization and last use optimization.
This is an experimental version of ergonomic ref counting
RFC: rust-lang/rfcs#3680
Tracking issue: #132290
Project goal: rust-lang/rust-project-goals#107
r? @nikomatsakis