Begin AST lowering for precise captures

This commit is contained in:
Michael Goulet 2024-04-03 20:54:23 -04:00
parent a076eae0d2
commit 647b672f16
5 changed files with 106 additions and 29 deletions

View File

@ -1399,7 +1399,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
hir::TyKind::TraitObject(bounds, lifetime_bound, *kind) hir::TyKind::TraitObject(bounds, lifetime_bound, *kind)
} }
TyKind::ImplTrait(def_node_id, bounds, precise_capturing) => { TyKind::ImplTrait(def_node_id, bounds, precise_capturing) => {
assert!(precise_capturing.is_none(), "precise captures not supported yet!");
let span = t.span; let span = t.span;
match itctx { match itctx {
ImplTraitContext::OpaqueTy { origin, fn_kind } => self.lower_opaque_impl_trait( ImplTraitContext::OpaqueTy { origin, fn_kind } => self.lower_opaque_impl_trait(
@ -1409,8 +1408,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
bounds, bounds,
fn_kind, fn_kind,
itctx, itctx,
precise_capturing.as_deref(),
), ),
ImplTraitContext::Universal => { ImplTraitContext::Universal => {
assert!(
precise_capturing.is_none(),
"TODO: precise captures not supported on universals!"
);
let span = t.span; let span = t.span;
// HACK: pprust breaks strings with newlines when the type // HACK: pprust breaks strings with newlines when the type
@ -1521,6 +1525,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
bounds: &GenericBounds, bounds: &GenericBounds,
fn_kind: Option<FnDeclKind>, fn_kind: Option<FnDeclKind>,
itctx: ImplTraitContext, itctx: ImplTraitContext,
precise_capturing: Option<&ast::GenericArgs>,
) -> hir::TyKind<'hir> { ) -> hir::TyKind<'hir> {
// Make sure we know that some funky desugaring has been going on here. // Make sure we know that some funky desugaring has been going on here.
// This is a first: there is code in other places like for loop // This is a first: there is code in other places like for loop
@ -1529,7 +1534,22 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
// frequently opened issues show. // frequently opened issues show.
let opaque_ty_span = self.mark_span_with_reason(DesugaringKind::OpaqueTy, span, None); let opaque_ty_span = self.mark_span_with_reason(DesugaringKind::OpaqueTy, span, None);
let captured_lifetimes_to_duplicate = match origin { let captured_lifetimes_to_duplicate = if let Some(precise_capturing) = precise_capturing {
let ast::GenericArgs::AngleBracketed(precise_capturing) = precise_capturing else {
panic!("we only parse angle-bracketed args")
};
// We'll actually validate these later on; all we need is the list of
// lifetimes to duplicate during this portion of lowering.
precise_capturing
.args
.iter()
.filter_map(|arg| match arg {
ast::AngleBracketedArg::Arg(ast::GenericArg::Lifetime(lt)) => Some(*lt),
_ => None,
})
.collect()
} else {
match origin {
hir::OpaqueTyOrigin::TyAlias { .. } => { hir::OpaqueTyOrigin::TyAlias { .. } => {
// type alias impl trait and associated type position impl trait were // type alias impl trait and associated type position impl trait were
// decided to capture all in-scope lifetimes, which we collect for // decided to capture all in-scope lifetimes, which we collect for
@ -1564,6 +1584,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
hir::OpaqueTyOrigin::AsyncFn(..) => { hir::OpaqueTyOrigin::AsyncFn(..) => {
unreachable!("should be using `lower_async_fn_ret_ty`") unreachable!("should be using `lower_async_fn_ret_ty`")
} }
}
}; };
debug!(?captured_lifetimes_to_duplicate); debug!(?captured_lifetimes_to_duplicate);

View File

@ -0,0 +1,18 @@
//@ check-pass
// Show how precise captures allow us to skip capturing a higher-ranked lifetime
#![feature(lifetime_capture_rules_2024, precise_capturing)]
//~^ WARN the feature `precise_capturing` is incomplete
trait Trait<'a> {
type Item;
}
impl Trait<'_> for () {
type Item = Vec<()>;
}
fn hello() -> impl for<'a> Trait<'a, Item = impl use<> IntoIterator> {}
fn main() {}

View File

@ -0,0 +1,11 @@
warning: the feature `precise_capturing` is incomplete and may not be safe to use and/or cause compiler crashes
--> $DIR/higher-ranked.rs:5:41
|
LL | #![feature(lifetime_capture_rules_2024, precise_capturing)]
| ^^^^^^^^^^^^^^^^^
|
= note: see issue #123432 <https://github.com/rust-lang/rust/issues/123432> for more information
= note: `#[warn(incomplete_features)]` on by default
warning: 1 warning emitted

View File

@ -0,0 +1,16 @@
//@ check-pass
// Show that precise captures allow us to skip a lifetime param for outlives
#![feature(lifetime_capture_rules_2024, precise_capturing)]
//~^ WARN the feature `precise_capturing` is incomplete
fn hello<'a: 'a, 'b: 'b>() -> impl use<'a> Sized { }
fn outlives<'a, T: 'a>(_: T) {}
fn test<'a, 'b>() {
outlives::<'a, _>(hello::<'a, 'b>());
}
fn main() {}

View File

@ -0,0 +1,11 @@
warning: the feature `precise_capturing` is incomplete and may not be safe to use and/or cause compiler crashes
--> $DIR/outlives.rs:5:41
|
LL | #![feature(lifetime_capture_rules_2024, precise_capturing)]
| ^^^^^^^^^^^^^^^^^
|
= note: see issue #123432 <https://github.com/rust-lang/rust/issues/123432> for more information
= note: `#[warn(incomplete_features)]` on by default
warning: 1 warning emitted