Skip to content

Commit 86b2819

Browse files
committed
Allow impl Fn() -> impl Trait
This allows writing the following function signatures: ```rust fn f0() -> impl Fn() -> impl Trait; fn f1(_: impl Fn() -> impl Trait); fn f2<F: Fn() -> impl Trait>(_: F); fn f3() -> &'static dyn Fn() -> impl Trait; fn f4(_: &dyn Fn() -> impl Trait); ``` All of the above are already allowed with common traits and associated types, there is no reason why `Fn*` traits should be special in this regard.
1 parent 9ad5d82 commit 86b2819

File tree

5 files changed

+52
-92
lines changed

5 files changed

+52
-92
lines changed

Diff for: compiler/rustc_ast_lowering/src/path.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
222222
self.lower_angle_bracketed_parameter_data(data, param_mode, itctx)
223223
}
224224
GenericArgs::Parenthesized(ref data) => match parenthesized_generic_args {
225-
ParenthesizedGenericArgs::Ok => self.lower_parenthesized_parameter_data(data),
225+
ParenthesizedGenericArgs::Ok => {
226+
self.lower_parenthesized_parameter_data(data, itctx)
227+
}
226228
ParenthesizedGenericArgs::Err => {
227229
let mut err = struct_span_err!(self.sess, data.span, E0214, "{}", msg);
228230
err.span_label(data.span, "only `Fn` traits may use parentheses");
@@ -384,6 +386,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
384386
fn lower_parenthesized_parameter_data(
385387
&mut self,
386388
data: &ParenthesizedArgs,
389+
itctx: ImplTraitContext<'_, 'hir>,
387390
) -> (GenericArgsCtor<'hir>, bool) {
388391
// Switch to `PassThrough` mode for anonymous lifetimes; this
389392
// means that we permit things like `&Ref<T>`, where `Ref` has
@@ -396,7 +399,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
396399
inputs.iter().map(|ty| this.lower_ty_direct(ty, ImplTraitContext::disallowed())),
397400
);
398401
let output_ty = match output {
399-
FnRetTy::Ty(ty) => this.lower_ty(&ty, ImplTraitContext::disallowed()),
402+
FnRetTy::Ty(ty) => this.lower_ty(&ty, itctx),
400403
FnRetTy::Default(_) => this.arena.alloc(this.ty_tup(*span, &[])),
401404
};
402405
let args = smallvec![GenericArg::Type(this.ty_tup(*inputs_span, inputs))];

Diff for: src/test/ui/impl-trait/nested_impl_trait.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,7 @@ fn allowed_in_assoc_type() -> impl Iterator<Item=impl Fn()> {
2323
}
2424

2525
fn allowed_in_ret_type() -> impl Fn() -> impl Into<u32> {
26-
//~^ `impl Trait` not allowed
27-
|| 5
26+
|| 5u8
2827
}
2928

3029
fn main() {}

Diff for: src/test/ui/impl-trait/nested_impl_trait.stderr

+1-7
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,7 @@ error[E0562]: `impl Trait` not allowed outside of function and method return typ
4040
LL | fn bad_in_fn_syntax(x: fn() -> impl Into<impl Debug>) {}
4141
| ^^^^^^^^^^^^^^^^^^^^^
4242

43-
error[E0562]: `impl Trait` not allowed outside of function and method return types
44-
--> $DIR/nested_impl_trait.rs:25:42
45-
|
46-
LL | fn allowed_in_ret_type() -> impl Fn() -> impl Into<u32> {
47-
| ^^^^^^^^^^^^^^
48-
49-
error: aborting due to 6 previous errors
43+
error: aborting due to 5 previous errors
5044

5145
Some errors have detailed explanations: E0562, E0666.
5246
For more information about an error, try `rustc --explain E0562`.

Diff for: src/test/ui/impl-trait/where-allowed.rs

+5-11
Original file line numberDiff line numberDiff line change
@@ -31,44 +31,38 @@ fn in_fn_return_in_return() -> fn() -> impl Debug { panic!() }
3131
fn in_dyn_Fn_parameter_in_parameters(_: &dyn Fn(impl Debug)) { panic!() }
3232
//~^ ERROR `impl Trait` not allowed outside of function and method return types
3333

34-
// Disallowed
34+
// Allowed
3535
fn in_dyn_Fn_return_in_parameters(_: &dyn Fn() -> impl Debug) { panic!() }
36-
//~^ ERROR `impl Trait` not allowed outside of function and method return types
3736

3837
// Disallowed
3938
fn in_dyn_Fn_parameter_in_return() -> &'static dyn Fn(impl Debug) { panic!() }
4039
//~^ ERROR `impl Trait` not allowed outside of function and method return types
4140

42-
// Disallowed
41+
// Allowed
4342
fn in_dyn_Fn_return_in_return() -> &'static dyn Fn() -> impl Debug { panic!() }
44-
//~^ ERROR `impl Trait` not allowed outside of function and method return types
4543

4644
// Disallowed
4745
fn in_impl_Fn_parameter_in_parameters(_: &impl Fn(impl Debug)) { panic!() }
4846
//~^ ERROR `impl Trait` not allowed outside of function and method return types
4947
//~^^ ERROR nested `impl Trait` is not allowed
5048

51-
// Disallowed
49+
// Allowed
5250
fn in_impl_Fn_return_in_parameters(_: &impl Fn() -> impl Debug) { panic!() }
53-
//~^ ERROR `impl Trait` not allowed outside of function and method return types
5451

5552
// Disallowed
5653
fn in_impl_Fn_parameter_in_return() -> &'static impl Fn(impl Debug) { panic!() }
5754
//~^ ERROR `impl Trait` not allowed outside of function and method return types
5855
//~| ERROR nested `impl Trait` is not allowed
5956

60-
// Disallowed
57+
// Allowed
6158
fn in_impl_Fn_return_in_return() -> &'static impl Fn() -> impl Debug { panic!() }
62-
//~^ ERROR `impl Trait` not allowed outside of function and method return types
6359

6460
// Disallowed
6561
fn in_Fn_parameter_in_generics<F: Fn(impl Debug)> (_: F) { panic!() }
6662
//~^ ERROR `impl Trait` not allowed outside of function and method return types
6763

68-
// Disallowed
64+
// Allowed
6965
fn in_Fn_return_in_generics<F: Fn() -> impl Debug> (_: F) { panic!() }
70-
//~^ ERROR `impl Trait` not allowed outside of function and method return types
71-
7266

7367
// Allowed
7468
fn in_impl_Trait_in_parameters(_: impl Iterator<Item = impl Iterator>) { panic!() }

0 commit comments

Comments
 (0)