Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow impl Fn() -> impl Trait #93082

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions compiler/rustc_ast_lowering/src/path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
self.lower_angle_bracketed_parameter_data(data, param_mode, itctx)
}
GenericArgs::Parenthesized(ref data) => match parenthesized_generic_args {
ParenthesizedGenericArgs::Ok => self.lower_parenthesized_parameter_data(data),
ParenthesizedGenericArgs::Ok => {
self.lower_parenthesized_parameter_data(data, itctx)
}
ParenthesizedGenericArgs::Err => {
let mut err = struct_span_err!(self.sess, data.span, E0214, "{}", msg);
err.span_label(data.span, "only `Fn` traits may use parentheses");
Expand Down Expand Up @@ -384,6 +386,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
fn lower_parenthesized_parameter_data(
&mut self,
data: &ParenthesizedArgs,
itctx: ImplTraitContext<'_, 'hir>,
) -> (GenericArgsCtor<'hir>, bool) {
// Switch to `PassThrough` mode for anonymous lifetimes; this
// means that we permit things like `&Ref<T>`, where `Ref` has
Expand All @@ -396,7 +399,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
inputs.iter().map(|ty| this.lower_ty_direct(ty, ImplTraitContext::disallowed())),
);
let output_ty = match output {
FnRetTy::Ty(ty) => this.lower_ty(&ty, ImplTraitContext::disallowed()),
FnRetTy::Ty(ty) => this.lower_ty(&ty, itctx),
FnRetTy::Default(_) => this.arena.alloc(this.ty_tup(*span, &[])),
};
let args = smallvec![GenericArg::Type(this.ty_tup(*inputs_span, inputs))];
Expand Down
16 changes: 16 additions & 0 deletions src/test/ui/impl-trait/impl_fn_associativity.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// run-pass
use std::fmt::Debug;

fn f_debug() -> impl Fn() -> impl Debug {
|| ()
}

fn ff_debug() -> impl Fn() -> impl Fn() -> impl Debug {
|| f_debug()
}

fn main() {
// Check that `ff_debug` is `() -> (() -> Debug)` and not `(() -> ()) -> Debug`
let debug = ff_debug()()();
assert_eq!(format!("{:?}", debug), "()");
}
3 changes: 1 addition & 2 deletions src/test/ui/impl-trait/nested_impl_trait.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,7 @@ fn allowed_in_assoc_type() -> impl Iterator<Item=impl Fn()> {
}

fn allowed_in_ret_type() -> impl Fn() -> impl Into<u32> {
//~^ `impl Trait` not allowed
|| 5
|| 5u8
}

fn main() {}
8 changes: 1 addition & 7 deletions src/test/ui/impl-trait/nested_impl_trait.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,7 @@ error[E0562]: `impl Trait` not allowed outside of function and method return typ
LL | fn bad_in_fn_syntax(x: fn() -> impl Into<impl Debug>) {}
| ^^^^^^^^^^^^^^^^^^^^^

error[E0562]: `impl Trait` not allowed outside of function and method return types
--> $DIR/nested_impl_trait.rs:25:42
|
LL | fn allowed_in_ret_type() -> impl Fn() -> impl Into<u32> {
| ^^^^^^^^^^^^^^

error: aborting due to 6 previous errors
error: aborting due to 5 previous errors

Some errors have detailed explanations: E0562, E0666.
For more information about an error, try `rustc --explain E0562`.
16 changes: 5 additions & 11 deletions src/test/ui/impl-trait/where-allowed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,44 +31,38 @@ fn in_fn_return_in_return() -> fn() -> impl Debug { panic!() }
fn in_dyn_Fn_parameter_in_parameters(_: &dyn Fn(impl Debug)) { panic!() }
//~^ ERROR `impl Trait` not allowed outside of function and method return types

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

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

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

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

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

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

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

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

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


// Allowed
fn in_impl_Trait_in_parameters(_: impl Iterator<Item = impl Iterator>) { panic!() }
Expand Down
Loading