Auto merge of #123468 - compiler-errors:precise-capturing, r=oli-obk
Implement syntax for `impl Trait` to specify its captures explicitly (`feature(precise_capturing)`) Implements `impl use<'a, 'b, T, U> Sized` syntax that allows users to explicitly list the captured parameters for an opaque, rather than inferring it from the opaque's bounds (or capturing *all* lifetimes under 2024-edition capture rules). This allows us to exclude some implicit captures, so this syntax may be used as a migration strategy for changes due to #117587. We represent this list of captured params as `PreciseCapturingArg` in AST and HIR, resolving them between `rustc_resolve` and `resolve_bound_vars`. Later on, we validate that the opaques only capture the parameters in this list. We artificially limit the feature to *require* mentioning all type and const parameters, since we don't currently have support for non-lifetime bivariant generics. This can be relaxed in the future. We also may need to limit this to require naming *all* lifetime parameters for RPITIT, since GATs have no variance. I have to investigate this. This can also be relaxed in the future. r? `@oli-obk` Tracking issue: - https://github.com/rust-lang/rust/issues/123432
This commit is contained in:
commit
4e1f5d90bc
55 changed files with 1033 additions and 71 deletions
|
@ -63,7 +63,7 @@ impl fmt::Debug for Label {
|
|||
|
||||
/// A "Lifetime" is an annotation of the scope in which variable
|
||||
/// can be used, e.g. `'a` in `&'a i32`.
|
||||
#[derive(Clone, Encodable, Decodable, Copy, PartialEq, Eq)]
|
||||
#[derive(Clone, Encodable, Decodable, Copy, PartialEq, Eq, Hash)]
|
||||
pub struct Lifetime {
|
||||
pub id: NodeId,
|
||||
pub ident: Ident,
|
||||
|
@ -2132,7 +2132,7 @@ pub enum TyKind {
|
|||
/// The `NodeId` exists to prevent lowering from having to
|
||||
/// generate `NodeId`s on the fly, which would complicate
|
||||
/// the generation of opaque `type Foo = impl Trait` items significantly.
|
||||
ImplTrait(NodeId, GenericBounds),
|
||||
ImplTrait(NodeId, GenericBounds, Option<P<(ThinVec<PreciseCapturingArg>, Span)>>),
|
||||
/// No-op; kept solely so that we can pretty-print faithfully.
|
||||
Paren(P<Ty>),
|
||||
/// Unused for now.
|
||||
|
@ -2188,6 +2188,14 @@ pub enum TraitObjectSyntax {
|
|||
None,
|
||||
}
|
||||
|
||||
#[derive(Clone, Encodable, Decodable, Debug)]
|
||||
pub enum PreciseCapturingArg {
|
||||
/// Lifetime parameter
|
||||
Lifetime(Lifetime),
|
||||
/// Type or const parameter
|
||||
Arg(Path, NodeId),
|
||||
}
|
||||
|
||||
/// Inline assembly operand explicit register or register class.
|
||||
///
|
||||
/// E.g., `"eax"` as in `asm!("mov eax, 2", out("eax") result)`.
|
||||
|
|
|
@ -259,6 +259,10 @@ pub trait MutVisitor: Sized {
|
|||
noop_visit_param_bound(tpb, self);
|
||||
}
|
||||
|
||||
fn visit_precise_capturing_arg(&mut self, arg: &mut PreciseCapturingArg) {
|
||||
noop_visit_precise_capturing_arg(arg, self);
|
||||
}
|
||||
|
||||
fn visit_mt(&mut self, mt: &mut MutTy) {
|
||||
noop_visit_mt(mt, self);
|
||||
}
|
||||
|
@ -518,9 +522,14 @@ pub fn noop_visit_ty<T: MutVisitor>(ty: &mut P<Ty>, vis: &mut T) {
|
|||
TyKind::TraitObject(bounds, _syntax) => {
|
||||
visit_vec(bounds, |bound| vis.visit_param_bound(bound))
|
||||
}
|
||||
TyKind::ImplTrait(id, bounds) => {
|
||||
TyKind::ImplTrait(id, bounds, precise_capturing) => {
|
||||
vis.visit_id(id);
|
||||
visit_vec(bounds, |bound| vis.visit_param_bound(bound));
|
||||
if let Some((precise_capturing, _span)) = precise_capturing.as_deref_mut() {
|
||||
for arg in precise_capturing {
|
||||
vis.visit_precise_capturing_arg(arg);
|
||||
}
|
||||
}
|
||||
}
|
||||
TyKind::MacCall(mac) => vis.visit_mac_call(mac),
|
||||
TyKind::AnonStruct(id, fields) | TyKind::AnonUnion(id, fields) => {
|
||||
|
@ -914,6 +923,18 @@ pub fn noop_visit_param_bound<T: MutVisitor>(pb: &mut GenericBound, vis: &mut T)
|
|||
}
|
||||
}
|
||||
|
||||
pub fn noop_visit_precise_capturing_arg<T: MutVisitor>(arg: &mut PreciseCapturingArg, vis: &mut T) {
|
||||
match arg {
|
||||
PreciseCapturingArg::Lifetime(lt) => {
|
||||
vis.visit_lifetime(lt);
|
||||
}
|
||||
PreciseCapturingArg::Arg(path, id) => {
|
||||
vis.visit_path(path);
|
||||
vis.visit_id(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn noop_flat_map_generic_param<T: MutVisitor>(
|
||||
mut param: GenericParam,
|
||||
vis: &mut T,
|
||||
|
|
|
@ -184,6 +184,9 @@ pub trait Visitor<'ast>: Sized {
|
|||
fn visit_param_bound(&mut self, bounds: &'ast GenericBound, _ctxt: BoundKind) -> Self::Result {
|
||||
walk_param_bound(self, bounds)
|
||||
}
|
||||
fn visit_precise_capturing_arg(&mut self, arg: &'ast PreciseCapturingArg) {
|
||||
walk_precise_capturing_arg(self, arg);
|
||||
}
|
||||
fn visit_poly_trait_ref(&mut self, t: &'ast PolyTraitRef) -> Self::Result {
|
||||
walk_poly_trait_ref(self, t)
|
||||
}
|
||||
|
@ -457,8 +460,13 @@ pub fn walk_ty<'a, V: Visitor<'a>>(visitor: &mut V, typ: &'a Ty) -> V::Result {
|
|||
TyKind::TraitObject(bounds, ..) => {
|
||||
walk_list!(visitor, visit_param_bound, bounds, BoundKind::TraitObject);
|
||||
}
|
||||
TyKind::ImplTrait(_, bounds) => {
|
||||
TyKind::ImplTrait(_, bounds, precise_capturing) => {
|
||||
walk_list!(visitor, visit_param_bound, bounds, BoundKind::Impl);
|
||||
if let Some((precise_capturing, _span)) = precise_capturing.as_deref() {
|
||||
for arg in precise_capturing {
|
||||
try_visit!(visitor.visit_precise_capturing_arg(arg));
|
||||
}
|
||||
}
|
||||
}
|
||||
TyKind::Typeof(expression) => try_visit!(visitor.visit_anon_const(expression)),
|
||||
TyKind::Infer | TyKind::ImplicitSelf | TyKind::Dummy | TyKind::Err(_) => {}
|
||||
|
@ -637,6 +645,20 @@ pub fn walk_param_bound<'a, V: Visitor<'a>>(visitor: &mut V, bound: &'a GenericB
|
|||
}
|
||||
}
|
||||
|
||||
pub fn walk_precise_capturing_arg<'a, V: Visitor<'a>>(
|
||||
visitor: &mut V,
|
||||
arg: &'a PreciseCapturingArg,
|
||||
) {
|
||||
match arg {
|
||||
PreciseCapturingArg::Lifetime(lt) => {
|
||||
visitor.visit_lifetime(lt, LifetimeCtxt::GenericArg);
|
||||
}
|
||||
PreciseCapturingArg::Arg(path, id) => {
|
||||
visitor.visit_path(path, *id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn walk_generic_param<'a, V: Visitor<'a>>(
|
||||
visitor: &mut V,
|
||||
param: &'a GenericParam,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue