diff --git a/compiler/rustc_ast_lowering/messages.ftl b/compiler/rustc_ast_lowering/messages.ftl index 7d81e45d314..57b9d904dc2 100644 --- a/compiler/rustc_ast_lowering/messages.ftl +++ b/compiler/rustc_ast_lowering/messages.ftl @@ -130,6 +130,9 @@ ast_lowering_never_pattern_with_guard = ast_lowering_no_precise_captures_on_apit = `use<...>` precise capturing syntax not allowed in argument-position `impl Trait` +ast_lowering_no_precise_captures_on_rpitit = `use<...>` precise capturing syntax is currently not allowed in return-position `impl Trait` in traits + .note = currently, return-position `impl Trait` in traits and trait implementations capture all lifetimes in scope + ast_lowering_previously_used_here = previously used here ast_lowering_register1 = register `{$reg1_name}` diff --git a/compiler/rustc_ast_lowering/src/errors.rs b/compiler/rustc_ast_lowering/src/errors.rs index 02744d16b42..3d4b6a1f033 100644 --- a/compiler/rustc_ast_lowering/src/errors.rs +++ b/compiler/rustc_ast_lowering/src/errors.rs @@ -424,6 +424,14 @@ pub(crate) struct NoPreciseCapturesOnApit { pub span: Span, } +#[derive(Diagnostic)] +#[diag(ast_lowering_no_precise_captures_on_rpitit)] +#[note] +pub(crate) struct NoPreciseCapturesOnRpitit { + #[primary_span] + pub span: Span, +} + #[derive(Diagnostic)] #[diag(ast_lowering_yield_in_closure)] pub(crate) struct YieldInClosure { diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index da8682d3d09..0a06304fcec 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -1594,6 +1594,26 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { }; debug!(?captured_lifetimes_to_duplicate); + match fn_kind { + // Deny `use<>` on RPITIT in trait/trait-impl for now. + Some(FnDeclKind::Trait | FnDeclKind::Impl) => { + if let Some(span) = bounds.iter().find_map(|bound| match *bound { + ast::GenericBound::Use(_, span) => Some(span), + _ => None, + }) { + self.tcx.dcx().emit_err(errors::NoPreciseCapturesOnRpitit { span }); + } + } + None + | Some( + FnDeclKind::Fn + | FnDeclKind::Inherent + | FnDeclKind::ExternFn + | FnDeclKind::Closure + | FnDeclKind::Pointer, + ) => {} + } + self.lower_opaque_inner( opaque_ty_node_id, origin, diff --git a/tests/ui/impl-trait/precise-capturing/forgot-to-capture-type.rs b/tests/ui/impl-trait/precise-capturing/forgot-to-capture-type.rs index 08014985783..0028a45cbf3 100644 --- a/tests/ui/impl-trait/precise-capturing/forgot-to-capture-type.rs +++ b/tests/ui/impl-trait/precise-capturing/forgot-to-capture-type.rs @@ -6,6 +6,7 @@ fn type_param() -> impl Sized + use<> {} trait Foo { fn bar() -> impl Sized + use<>; //~^ ERROR `impl Trait` must mention the `Self` type of the trait + //~| ERROR `use<...>` precise capturing syntax is currently not allowed in return-position `impl Trait` in traits } fn main() {} diff --git a/tests/ui/impl-trait/precise-capturing/forgot-to-capture-type.stderr b/tests/ui/impl-trait/precise-capturing/forgot-to-capture-type.stderr index 93b44a0c18c..89bd4df4431 100644 --- a/tests/ui/impl-trait/precise-capturing/forgot-to-capture-type.stderr +++ b/tests/ui/impl-trait/precise-capturing/forgot-to-capture-type.stderr @@ -1,3 +1,11 @@ +error: `use<...>` precise capturing syntax is currently not allowed in return-position `impl Trait` in traits + --> $DIR/forgot-to-capture-type.rs:7:30 + | +LL | fn bar() -> impl Sized + use<>; + | ^^^^^ + | + = note: currently, return-position `impl Trait` in traits and trait implementations capture all lifetimes in scope + error: `impl Trait` must mention all type parameters in scope in `use<...>` --> $DIR/forgot-to-capture-type.rs:3:23 | @@ -18,5 +26,5 @@ LL | fn bar() -> impl Sized + use<>; | = note: currently, all type parameters are required to be mentioned in the precise captures list -error: aborting due to 2 previous errors +error: aborting due to 3 previous errors diff --git a/tests/ui/impl-trait/precise-capturing/redundant.normal.stderr b/tests/ui/impl-trait/precise-capturing/redundant.normal.stderr new file mode 100644 index 00000000000..44bc9f7daad --- /dev/null +++ b/tests/ui/impl-trait/precise-capturing/redundant.normal.stderr @@ -0,0 +1,20 @@ +warning: all possible in-scope parameters are already captured, so `use<...>` syntax is redundant + --> $DIR/redundant.rs:7:19 + | +LL | fn hello<'a>() -> impl Sized + use<'a> {} + | ^^^^^^^^^^^^^------- + | | + | help: remove the `use<...>` syntax + | + = note: `#[warn(impl_trait_redundant_captures)]` on by default + +warning: all possible in-scope parameters are already captured, so `use<...>` syntax is redundant + --> $DIR/redundant.rs:12:27 + | +LL | fn inherent(&self) -> impl Sized + use<'_> {} + | ^^^^^^^^^^^^^------- + | | + | help: remove the `use<...>` syntax + +warning: 2 warnings emitted + diff --git a/tests/ui/impl-trait/precise-capturing/redundant.rpitit.stderr b/tests/ui/impl-trait/precise-capturing/redundant.rpitit.stderr new file mode 100644 index 00000000000..9aa73353126 --- /dev/null +++ b/tests/ui/impl-trait/precise-capturing/redundant.rpitit.stderr @@ -0,0 +1,18 @@ +error: `use<...>` precise capturing syntax is currently not allowed in return-position `impl Trait` in traits + --> $DIR/redundant.rs:18:35 + | +LL | fn in_trait() -> impl Sized + use<'a, Self>; + | ^^^^^^^^^^^^^ + | + = note: currently, return-position `impl Trait` in traits and trait implementations capture all lifetimes in scope + +error: `use<...>` precise capturing syntax is currently not allowed in return-position `impl Trait` in traits + --> $DIR/redundant.rs:23:35 + | +LL | fn in_trait() -> impl Sized + use<'a> {} + | ^^^^^^^ + | + = note: currently, return-position `impl Trait` in traits and trait implementations capture all lifetimes in scope + +error: aborting due to 2 previous errors + diff --git a/tests/ui/impl-trait/precise-capturing/redundant.rs b/tests/ui/impl-trait/precise-capturing/redundant.rs index 99c128fdc48..ef4f05bd7e4 100644 --- a/tests/ui/impl-trait/precise-capturing/redundant.rs +++ b/tests/ui/impl-trait/precise-capturing/redundant.rs @@ -1,24 +1,27 @@ //@ compile-flags: -Zunstable-options --edition=2024 -//@ check-pass +//@ revisions: normal rpitit +//@[normal] check-pass #![feature(precise_capturing)] fn hello<'a>() -> impl Sized + use<'a> {} -//~^ WARN all possible in-scope parameters are already captured +//[normal]~^ WARN all possible in-scope parameters are already captured struct Inherent; impl Inherent { fn inherent(&self) -> impl Sized + use<'_> {} - //~^ WARN all possible in-scope parameters are already captured + //[normal]~^ WARN all possible in-scope parameters are already captured } +#[cfg(rpitit)] trait Test<'a> { fn in_trait() -> impl Sized + use<'a, Self>; - //~^ WARN all possible in-scope parameters are already captured + //[rpitit]~^ ERROR `use<...>` precise capturing syntax is currently not allowed in return-position `impl Trait` in traits } +#[cfg(rpitit)] impl<'a> Test<'a> for () { fn in_trait() -> impl Sized + use<'a> {} - //~^ WARN all possible in-scope parameters are already captured + //[rpitit]~^ ERROR `use<...>` precise capturing syntax is currently not allowed in return-position `impl Trait` in traits } fn main() {} diff --git a/tests/ui/impl-trait/precise-capturing/redundant.stderr b/tests/ui/impl-trait/precise-capturing/redundant.stderr deleted file mode 100644 index 274d9d2375f..00000000000 --- a/tests/ui/impl-trait/precise-capturing/redundant.stderr +++ /dev/null @@ -1,36 +0,0 @@ -warning: all possible in-scope parameters are already captured, so `use<...>` syntax is redundant - --> $DIR/redundant.rs:6:19 - | -LL | fn hello<'a>() -> impl Sized + use<'a> {} - | ^^^^^^^^^^^^^------- - | | - | help: remove the `use<...>` syntax - | - = note: `#[warn(impl_trait_redundant_captures)]` on by default - -warning: all possible in-scope parameters are already captured, so `use<...>` syntax is redundant - --> $DIR/redundant.rs:11:27 - | -LL | fn inherent(&self) -> impl Sized + use<'_> {} - | ^^^^^^^^^^^^^------- - | | - | help: remove the `use<...>` syntax - -warning: all possible in-scope parameters are already captured, so `use<...>` syntax is redundant - --> $DIR/redundant.rs:16:22 - | -LL | fn in_trait() -> impl Sized + use<'a, Self>; - | ^^^^^^^^^^^^^------------- - | | - | help: remove the `use<...>` syntax - -warning: all possible in-scope parameters are already captured, so `use<...>` syntax is redundant - --> $DIR/redundant.rs:20:22 - | -LL | fn in_trait() -> impl Sized + use<'a> {} - | ^^^^^^^^^^^^^------- - | | - | help: remove the `use<...>` syntax - -warning: 4 warnings emitted - diff --git a/tests/ui/impl-trait/precise-capturing/rpitit.stderr b/tests/ui/impl-trait/precise-capturing/rpitit.stderr index 202eeb39385..45eceef2f49 100644 --- a/tests/ui/impl-trait/precise-capturing/rpitit.stderr +++ b/tests/ui/impl-trait/precise-capturing/rpitit.stderr @@ -1,3 +1,11 @@ +error: `use<...>` precise capturing syntax is currently not allowed in return-position `impl Trait` in traits + --> $DIR/rpitit.rs:11:36 + | +LL | fn hello() -> impl PartialEq + use; + | ^^^^^^^^^ + | + = note: currently, return-position `impl Trait` in traits and trait implementations capture all lifetimes in scope + error: `impl Trait` captures lifetime parameter, but it is not mentioned in `use<...>` precise captures list --> $DIR/rpitit.rs:11:19 | @@ -38,5 +46,5 @@ LL | | ); help: `'a` and `'b` must be the same: replace one with the other -error: aborting due to 3 previous errors +error: aborting due to 4 previous errors diff --git a/tests/ui/impl-trait/precise-capturing/self-capture.rs b/tests/ui/impl-trait/precise-capturing/self-capture.rs index e0a4a8b658c..07bb417f9f7 100644 --- a/tests/ui/impl-trait/precise-capturing/self-capture.rs +++ b/tests/ui/impl-trait/precise-capturing/self-capture.rs @@ -1,9 +1,8 @@ -//@ check-pass - #![feature(precise_capturing)] trait Foo { fn bar<'a>() -> impl Sized + use; + //~^ ERROR `use<...>` precise capturing syntax is currently not allowed in return-position `impl Trait` in traits } fn main() {} diff --git a/tests/ui/impl-trait/precise-capturing/self-capture.stderr b/tests/ui/impl-trait/precise-capturing/self-capture.stderr new file mode 100644 index 00000000000..351de86dd5f --- /dev/null +++ b/tests/ui/impl-trait/precise-capturing/self-capture.stderr @@ -0,0 +1,10 @@ +error: `use<...>` precise capturing syntax is currently not allowed in return-position `impl Trait` in traits + --> $DIR/self-capture.rs:4:34 + | +LL | fn bar<'a>() -> impl Sized + use; + | ^^^^^^^^^ + | + = note: currently, return-position `impl Trait` in traits and trait implementations capture all lifetimes in scope + +error: aborting due to 1 previous error +