1
Fork 0

Rollup merge of #134797 - spastorino:ergonomic-ref-counting-1, r=nikomatsakis

Ergonomic ref counting

This is an experimental first version of ergonomic ref counting.

This first version implements most of the RFC but doesn't implement any of the optimizations. This was left for following iterations.

RFC: https://github.com/rust-lang/rfcs/pull/3680
Tracking issue: https://github.com/rust-lang/rust/issues/132290
Project goal: https://github.com/rust-lang/rust-project-goals/issues/107

r? ```@nikomatsakis```
This commit is contained in:
Matthias Krüger 2025-03-07 19:15:33 +01:00 committed by GitHub
commit f5a143f796
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
119 changed files with 1401 additions and 79 deletions

View file

@ -1533,6 +1533,11 @@ rustc_queries! {
query is_copy_raw(env: ty::PseudoCanonicalInput<'tcx, Ty<'tcx>>) -> bool {
desc { "computing whether `{}` is `Copy`", env.value }
}
/// Trait selection queries. These are best used by invoking `ty.is_use_cloned_modulo_regions()`,
/// `ty.is_use_cloned()`, etc, since that will prune the environment where possible.
query is_use_cloned_raw(env: ty::PseudoCanonicalInput<'tcx, Ty<'tcx>>) -> bool {
desc { "computing whether `{}` is `UseCloned`", env.value }
}
/// Query backing `Ty::is_sized`.
query is_sized_raw(env: ty::PseudoCanonicalInput<'tcx, Ty<'tcx>>) -> bool {
desc { "computing whether `{}` is `Sized`", env.value }

View file

@ -315,6 +315,14 @@ pub enum ExprKind<'tcx> {
/// (e.g. `foo(a, b)` in `x.foo(a, b)`).
fn_span: Span,
},
/// A use expression `x.use`.
ByUse {
/// The expression on which use is applied.
expr: ExprId,
/// The span of use, without the dot and receiver
/// (e.g. `use` in `x.use`).
span: Span,
},
/// A *non-overloaded* dereference.
Deref {
arg: ExprId,

View file

@ -59,6 +59,9 @@ pub fn walk_expr<'thir, 'tcx: 'thir, V: Visitor<'thir, 'tcx>>(
visitor.visit_expr(&visitor.thir()[arg]);
}
}
ByUse { expr, span: _ } => {
visitor.visit_expr(&visitor.thir()[expr]);
}
Deref { arg } => visitor.visit_expr(&visitor.thir()[arg]),
Binary { lhs, rhs, op: _ } | LogicalOp { lhs, rhs, op: _ } => {
visitor.visit_expr(&visitor.thir()[lhs]);

View file

@ -51,6 +51,9 @@ pub enum UpvarCapture {
/// depending on inference.
ByValue,
/// Upvar is captured by use. This is true when the closure is labeled `use`.
ByUse,
/// Upvar is captured by reference.
ByRef(BorrowKind),
}
@ -178,7 +181,7 @@ impl<'tcx> CapturedPlace<'tcx> {
pub fn is_by_ref(&self) -> bool {
match self.info.capture_kind {
ty::UpvarCapture::ByValue => false,
ty::UpvarCapture::ByValue | ty::UpvarCapture::ByUse => false,
ty::UpvarCapture::ByRef(..) => true,
}
}
@ -214,7 +217,7 @@ impl<'tcx> TyCtxt<'tcx> {
pub fn closure_captures(self, def_id: LocalDefId) -> &'tcx [&'tcx ty::CapturedPlace<'tcx>] {
if !self.is_closure_like(def_id.to_def_id()) {
return &[];
};
}
self.closure_typeinfo(def_id).captures
}
}

View file

@ -192,6 +192,18 @@ impl<'tcx> TyCtxt<'tcx> {
ty.is_trivially_pure_clone_copy() || self.is_copy_raw(typing_env.as_query_input(ty))
}
/// Checks whether `ty: UseCloned` holds while ignoring region constraints.
///
/// This function should not be used if there is an `InferCtxt` available.
/// Use `InferCtxt::type_is_copy_modulo_regions` instead.
pub fn type_is_use_cloned_modulo_regions(
self,
typing_env: ty::TypingEnv<'tcx>,
ty: Ty<'tcx>,
) -> bool {
ty.is_trivially_pure_clone_copy() || self.is_use_cloned_raw(typing_env.as_query_input(ty))
}
/// Returns the deeply last field of nested structures, or the same type if
/// not a structure at all. Corresponds to the only possible unsized field,
/// and its type can be used to determine unsizing strategy.